home *** CD-ROM | disk | FTP | other *** search
/ Everything For A Hacker / 19990506-[HACK].iso / DISK / NTCopy 1.0 (WinNT) / NTCopy.cpp next >
C/C++ Source or Header  |  1999-03-29  |  75KB  |  1,348 lines

  1. //---------------------------------------------------------------------------
  2. #define UNICODE
  3. #include <vcl\condefs.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <windows.h>
  8. #include <winioctl.h>
  9.  
  10. #pragma hdrstop
  11. //---------------------------------------------------------------------------
  12. USERES("NTCopy.res");
  13. //---------------------------------------------------------------------------
  14.  
  15. //---------------------------------------------------------------------------
  16. //  NTCopy
  17. //  ╙≥ΦδΦ≥α Σδ  Ωε∩Φ≡εΓαφΦ  ≥ε∞εΓ NTFS ± ±ε⌡≡αφσφΦσ∞ ≤±≥αφεΓδσφφ√⌡ ∩≡αΓ Σε±≥≤∩α
  18. //---------------------------------------------------------------------------
  19.  
  20. //---------------------------------------------------------------------------
  21. //  ╬∩≡σΣσδσφΦ  ΩεΣεΓ ταΓσ≡°σφΦ 
  22. //---------------------------------------------------------------------------
  23. #define EXIT_NOT_FOUND            1     // ∩≤≥ⁿ, ⌠αΘδ ΦδΦ Ωα≥αδεπ φσ φαΘΣσφ
  24. #define EXIT_ACCESS_DENIED        2     // Σε±≥≤∩ τα∩≡σ∙╕φ
  25. #define EXIT_ALREADY_EXISTS       4     // ⌠αΘδ ≤µσ ±≤∙σ±≥Γ≤σ≥
  26. #define EXIT_INCOMPATIBLE_TYPES   8     // φσ±εΓ∞σ≥Φ∞√σ ≥Φ∩√ Φ±≥ε≈φΦΩα Φ ÷σδΦ
  27. #define EXIT_INVALID_SWITCH      16     // φσΓσ≡φε ταΣαφφ√Θ Ωδ■≈
  28. #define EXIT_SYNTAX_ERROR        32     // ±Φφ≥αΩ±Φ≈σ±Ωα  ε°ΦßΩα Γ Ωε∞αφΣφεΘ ±≥≡εΩσ
  29. #define EXIT_NO_MEMORY           64     // φσΣε±≥α≥ε≈φε ∩α∞ ≥Φ
  30. #define EXIT_PRIVILEGE_CHECK     96     // φσΣε±≥α≥ε≈φ√Θ ≤≡εΓσφⁿ ∩≡ΦΓΦδσπΦΘ
  31. #define EXIT_INVALID_SYSTEM     128     // φσΣε∩≤±≥Φ∞α  Γσ≡±Φ  ε∩σ≡α÷ΦεφφεΘ ±Φ±≥σ∞√
  32. #define EXIT_SYSTEM_ERROR       160     // φσ≡α±∩ετφαφφα  ±Φ±≥σ∞φα  ε°ΦßΩα
  33.  
  34. //---------------------------------------------------------------------------
  35. //  ╬ß∙Φσ Σαφφ√σ
  36. //---------------------------------------------------------------------------
  37. void* WBuffer1 = NULL;                  // ≤Ωατα≥σδΦ φα ≡αßε≈Φσ ß≤⌠σ≡α
  38. void* WBuffer2 = NULL;
  39. char* OEMBuffer = NULL;                 // ≤Ωατα≥σδⁿ φα ß≤⌠σ≡ ∩σ≡σΩεΣΦ≡εΓΩΦ
  40. wchar_t* SourcePath = NULL;             // ≤Ωατα≥σδⁿ φα ß≤⌠σ≡ Φ±≥ε≈φΦΩα
  41. wchar_t* DestinationPath = NULL;        // ≤Ωατα≥σδⁿ φα ß≤⌠σ≡ ∩≡Φ╕∞φΦΩα
  42. char DiskOut = 0;                       // ⌠δαπ Γ√ΓεΣα Γ ΣΦ±ΩεΓ√Θ ⌠αΘδ
  43. char UseRussian = -1;                   // ⌠δαπ Φ±∩εδⁿτεΓαφΦ  ≡≤±±Ωεπε  τ√Ωα
  44. char OverwriteFiles = -1;               // ⌠δαπ ∩σ≡στα∩Φ±Φ ±≤∙σ±≥Γ≤■∙Φ⌡ ⌠αΘδεΓ
  45. char SkipCopy = 0;                      // ⌠δαπ ∩≡ε∩≤±Ωα Ωε∩Φ≡εΓαφΦ 
  46. char CopyRootRights = 0;                // ⌠δαπ Ωε∩Φ≡εΓαφΦ  ∩≡αΓ Σε±≥≤∩α Σδ  Ωε≡φσΓεπε Ωα≥αδεπα
  47. int ExitCode = 0;                       // ΩεΣ ταΓσ≡°σφΦ 
  48. WIN32_FIND_DATAW FileFinder;            // ß≤⌠σ≡ Σδ  ∩εΦ±Ωα ⌠αΘδεΓ
  49.  
  50. //---------------------------------------------------------------------------
  51. //  ShowAlert
  52. //  ╧≡ε÷σΣ≤≡α ⌠ε≡∞Φ≡εΓαφΦ  εΩφα ∩≡σΣ≤∩≡σµΣσφΦ 
  53. //---------------------------------------------------------------------------
  54. int ShowAlert (char* Message, UINT uIcon)
  55. {
  56.     char* pZero = strchr (Message, 0);  // φαΘ≥Φ ≡ατΣσδΦ≥σδⁿφ√Θ φεδⁿ
  57.     if (UseRussian < 0)
  58.     {
  59.         *pZero++ = '\n'; *pZero++ = '\n';   // ταßΦ≥ⁿ Σδ  ΣΓ≤ τ√≈φεπε Γ√ΓεΣα
  60.     }
  61.     else
  62.     {
  63.         pZero++; pZero++;               // ∩≡ε∩≤±≥Φ≥ⁿ
  64.     }
  65.     if (UseRussian <= 0) pZero = Message;   // ∩σ≡σ±≥αΓΦ≥ⁿ ≤Ωατα≥σδⁿ
  66.     return MessageBoxA (GetActiveWindow (), pZero, "NTCopy", uIcon);    // Γ√Γσ±≥Φ ±εεß∙σφΦσ
  67. }
  68.  
  69. //---------------------------------------------------------------------------
  70. //  ShowSystemAlert
  71. //  ╧≡ε÷σΣ≤≡α ⌠ε≡∞Φ≡εΓαφΦ  εΩφα ∩≡σΣ≤∩≡σµΣσφΦ  ε ≈Φ≈≥σ∞φεΘ ε°ΦßΩσ
  72. //---------------------------------------------------------------------------
  73. void ShowSystemAlert (int nErrorCode)
  74. {
  75.     char *cBuffer = stpcpy ((char*) WBuffer1, "SystemError ");  // αφπδΦΘ±Ωα  ±≥≡εΩα
  76.     sprintf (cBuffer, "%06d", nErrorCode);  // ∩≡σεß≡ατεΓα≥ⁿ ΩεΣ ε°ΦßΩΦ
  77.     cBuffer += 6;                       // ∩≡ε∩≤±≥Φ≥ⁿ ΩεΣ ε°ΦßΩΦ
  78.     *cBuffer++ = 0; *cBuffer++ = 0;     // ε≥ßΦΓΩα  τ√Ωα
  79.     cBuffer = stpcpy (cBuffer, "╤Φ±≥σ∞φα  ε°ΦßΩα ");    // ≡≤±±Ωα  ±≥≡εΩα
  80.     sprintf (cBuffer, "%06d", nErrorCode);  // ∩≡σεß≡ατεΓα≥ⁿ ΩεΣ ε°ΦßΩΦ
  81.     cBuffer += 6;                       // ∩≡ε∩≤±≥Φ≥ⁿ ΩεΣ ε°ΦßΩΦ
  82.     *cBuffer = 0;                       // ταΩ≡√≥ⁿ ±≥≡εΩ≤
  83.     ShowAlert ((char*) WBuffer1, MB_OK | MB_ICONSTOP);  // ±εεß∙Φ≥ⁿ ε ±≥≡α°φεΘ ε°ΦßΩσ
  84.     ExitCode |= EXIT_SYSTEM_ERROR;      // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  85. }
  86.  
  87. //---------------------------------------------------------------------------
  88. //  CheckSystemVersion
  89. //  ╧≡ε÷σΣ≤≡α ∩≡εΓσ≡ΩΦ Γσ≡±ΦΦ ε∩σ≡α÷ΦεφφεΘ ±Φ±≥σ∞√
  90. //---------------------------------------------------------------------------
  91. BOOL CheckSystemVersion (void)
  92. {
  93.     OSVERSIONINFOA OSVersion;           // Φφ⌠ε≡∞α÷Φ  ε Γσ≡±ΦΦ ±Φ±≥σ∞√
  94.     OSVersion.dwOSVersionInfoSize = sizeof (OSVERSIONINFOA);    // ταΣα≥ⁿ ≡ατ∞σ≡ ±≥≡≤Ω≥≤≡√
  95.     if (!GetVersionExA (&OSVersion))    // Φφ⌠ε≡∞α÷Φ■ ε Γσ≡±ΦΦ ∩εδ≤≈Φ≥ⁿ φσ ≤Σαδε±ⁿ
  96.     {
  97.         ShowAlert ("Can'n get operating system version\0\0═σΓετ∞εµφε ε∩≡σΣσδΦ≥ⁿ Γσ≡±Φ■ ε∩σ≡α÷ΦεφφεΘ ±Φ±≥σ∞√",
  98.           MB_OK | MB_ICONSTOP);
  99.         ExitCode |= EXIT_INVALID_SYSTEM;    // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  100.         return FALSE;
  101.     }
  102.     if (OSVersion.dwPlatformId != VER_PLATFORM_WIN32_NT)    // ²≥ε φσ Windows NT
  103.     {
  104.         ShowAlert ("This utility can work only under Windows NT\0\0▌≥α ∩≡επ≡α∞∞α ≡αßε≥ασ≥ ≥εδⁿΩε ∩εΣ ≤∩≡αΓδσφΦσ∞ Windows NT",
  105.           MB_OK | MB_ICONSTOP);
  106.         ExitCode |= EXIT_INVALID_SYSTEM;    // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  107.         return FALSE;
  108.     }
  109.     return TRUE;
  110. }
  111.  
  112. //---------------------------------------------------------------------------
  113. //  ParseSwitchesAlert
  114. //  ╧≡ε÷σΣ≤≡α εß≡αßε≥ΩΦ ε°ΦßΩΦ Γ Ωδ■≈σ
  115. //---------------------------------------------------------------------------
  116. void ParseSwitchesAlert (char* pSwitch, int ErrorMode)
  117. {
  118.     char MBuffer[1024];                 // ß≤⌠σ≡ Σδ  ±εεß∙σφΦ 
  119.     char* pMBuffer = stpcpy (MBuffer, "Invalid ");  // ∩σ≡Γ√Θ ⌠≡απ∞σφ≥ ±εεß∙σφΦ 
  120.     if (ErrorMode)                      // φσΓσ≡φεσ τφα≈σφΦσ Ωδ■≈α
  121.         pMBuffer = stpcpy (pMBuffer, "value of ");  // ≈≥ε Φ ε≥∞σ≥Φ≥ⁿ
  122.     pMBuffer = stpcpy (pMBuffer, "switch: ");
  123.     if (strlen (pSwitch) > 20)          // ±δΦ°Ωε∞ ΣδΦφφ√Θ Ωδ■≈
  124.         pMBuffer = ((char*) memcpy (pMBuffer, pSwitch, 20)) + 20;   // ±Ωε∩Φ≡εΓα≥ⁿ ⌠≡απ∞σφ≥
  125.     else pMBuffer = stpcpy (pMBuffer, pSwitch); // ΣεßαΓΦ≥ⁿ Γ Ωεφσ÷
  126.     pMBuffer = stpcpy (pMBuffer, " - ignored"); // τα ΓΦ≥ⁿ ε ∩≡ε∩≤±Ωσ
  127.     *pMBuffer++ = 0; *pMBuffer++ = 0;   // ≡ατΣσδΦ≥σδⁿ  τ√Ωα
  128.     pMBuffer = stpcpy (pMBuffer, "═σΣε∩≤±≥Φ∞"); // ∩σ≡Γ√Θ ⌠≡απ∞σφ≥ ∩ε-≡≤±±ΩΦ
  129.     if (ErrorMode)                      // φσΓσ≡φεσ τφα≈σφΦσ Ωδ■≈α
  130.         pMBuffer = stpcpy (pMBuffer, "εσ τφα≈σφΦσ Ωδ■≈α: ");
  131.     else pMBuffer = stpcpy (pMBuffer, "√Θ Ωδ■≈: ");
  132.     if (strlen (pSwitch) > 20)          // ±δΦ°Ωε∞ ΣδΦφφ√Θ Ωδ■≈
  133.         pMBuffer = ((char*) memcpy (pMBuffer, pSwitch, 20)) + 20;   // ±Ωε∩Φ≡εΓα≥ⁿ ⌠≡απ∞σφ≥
  134.     else pMBuffer = stpcpy (pMBuffer, pSwitch); // ΣεßαΓΦ≥ⁿ Γ Ωεφσ÷
  135.     pMBuffer = stpcpy (pMBuffer, " - Ωδ■≈ ∩≡ε∩≤∙σφ");   // τα ΓΦ≥ⁿ ε ∩≡ε∩≤±Ωσ
  136.     *pMBuffer = 0;                      // ταΩ≡√≥ⁿ ±εεß∙σφΦσ
  137.     ShowAlert (MBuffer, MB_OK | MB_ICONWARNING);    // Γ√Γσ±≥Φ ±εεß∙σφΦσ
  138.     ExitCode |= EXIT_INVALID_SWITCH;    // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  139. }
  140.  
  141. //---------------------------------------------------------------------------
  142. //  ParseSwitches
  143. //  ╧≡ε÷σΣ≤≡α ≡ατßε≡ΩΦ Ωδ■≈σΘ Ωε∞αφΣφεΘ ±≥≡εΩΦ
  144. //---------------------------------------------------------------------------
  145. void ParseSwitches (int argc, char** argv)
  146. {
  147.     for (int nArg = 1; nArg < argc; ++nArg)   // ÷ΦΩδ εßτε≡α ∩α≡α∞σ≥≡εΓ
  148.     {
  149.         char* pArg = argv[nArg];        // ε≈σ≡σΣφεΘ α≡π≤∞σφ≥
  150.         char cc = *pArg++;              // ∩σ≡Γ√Θ ±Φ∞Γεδ
  151.         if (cc == '-' || cc == '/')     // ²≥ε Ωδ■≈
  152.         {
  153.             cc = *pArg++;               // Φ∞  Ωδ■≈α
  154.             if (cc == 'l' || cc == 'L') // ≤∩≡αΓδσφΦσ  τ√Ωε∞
  155.             {
  156.                 cc = *pArg++;           // ε≈σ≡σΣφεΘ ±Φ∞Γεδ
  157.                 if (cc != ':')          // ²≥ε φσ ∩≡ΦτφαΩ τφα≈σφΦ 
  158.                     ParseSwitchesAlert (argv[nArg], (cc) ? 0 : 1); // φσΣε∩≤±≥Φ∞√Θ Ωδ■≈
  159.                 else
  160.                 {
  161.                     cc = *pArg++;       // ε≈σ≡σΣφεΘ ±Φ∞Γεδ
  162.                     if (!cc || *pArg)   // ±≥≡εΩα φσ ταΩεφ≈Φδα±ⁿ ΦδΦ ταΩεφ≈Φδα±ⁿ ±δΦ°Ωε∞ ≡αφε
  163.                         ParseSwitchesAlert (argv[nArg], 1); // φσΣε∩≤±≥Φ∞εσ τφα≈σφΦσ Ωδ■≈α
  164.                     else if (cc == 'e' || cc == 'E')    // αφπδΦΘ±ΩΦΘ  τ√Ω
  165.                         UseRussian = 0; // ε≥∞σ≥Φ≥ⁿ
  166.                     else if (cc == 'r' || cc == 'R')    // ≡≤±±ΩΦΘ  τ√Ω
  167.                         UseRussian = 1; // ε≥∞σ≥Φ≥ⁿ
  168.                     else ParseSwitchesAlert (argv[nArg], 1);    // φσΣε∩≤±≥Φ∞εσ τφα≈σφΦσ Ωδ■≈α
  169.                 }
  170.             }
  171.             else if (cc == 'o' || cc == 'O')    // ≤∩≡αΓδσφΦσ ∩σ≡στα∩Φ±ⁿ■ ⌠αΘδεΓ
  172.             {
  173.                 cc = *pArg++;           // ε≈σ≡σΣφεΘ ±Φ∞Γεδ
  174.                 if (cc != ':')          // ²≥ε φσ ∩≡ΦτφαΩ τφα≈σφΦ 
  175.                     ParseSwitchesAlert (argv[nArg], (cc) ? 0 : 1);  // φσΣε∩≤±≥Φ∞√Θ Ωδ■≈
  176.                 else
  177.                 {
  178.                     cc = *pArg++;       // ε≈σ≡σΣφεΘ ±Φ∞Γεδ
  179.                     if (!cc || *pArg)   // ±≥≡εΩα φσ ταΩεφ≈Φδα±ⁿ ΦδΦ ταΩεφ≈Φδα±ⁿ ±δΦ°Ωε∞ ≡αφε
  180.                         ParseSwitchesAlert (argv[nArg], 1); // φσΣε∩≤±≥Φ∞εσ τφα≈σφΦσ Ωδ■≈α
  181.                     else if (cc == 'y' || cc == 'Y')    // ∩σ≡στα∩Φ±√Γα≥ⁿ
  182.                         OverwriteFiles = 1; // ε≥∞σ≥Φ≥ⁿ
  183.                     else if (cc == 'n' || cc == 'N')    // φσ ∩σ≡στα∩Φ±√Γα≥ⁿ
  184.                         OverwriteFiles = 0; // ε≥∞σ≥Φ≥ⁿ
  185.                     else ParseSwitchesAlert (argv[nArg], 1);    // φσΣε∩≤±≥Φ∞εσ τφα≈σφΦσ Ωδ■≈α
  186.                 }
  187.             }
  188.             else if (cc == 's' || cc == 'S')    // ∩≡ε∩≤±Ω Ωε∩Φ≡εΓαφΦ 
  189.             {
  190.                 if (*pArg)              // ±≥≡εΩα φσ ταΩεφ≈Φδα±ⁿ
  191.                     ParseSwitchesAlert (argv[nArg], 0); // φσΣε∩≤±≥Φ∞√Θ Ωδ■≈
  192.                 else  SkipCopy = 1;     // ε≥∞σ≥Φ≥ⁿ
  193.             }
  194.             else if (cc == 'r' || cc == 'R')    // Ωε∩Φ≡εΓα≥ⁿ ∩≡αΓα Σε±≥≤∩α Ω Ωε≡φσΓε∞≤ Ωα≥αδεπ≤
  195.             {
  196.                 if (*pArg)              // ±≥≡εΩα φσ ταΩεφ≈Φδα±ⁿ
  197.                     ParseSwitchesAlert (argv[nArg], 0); // φσΣε∩≤±≥Φ∞√Θ Ωδ■≈
  198.                 else  CopyRootRights = 1;   // ε≥∞σ≥Φ≥ⁿ
  199.             }
  200.             else ParseSwitchesAlert (argv[nArg], 0);    // φσΣε∩≤±≥Φ∞√Θ Ωδ■≈
  201.         }
  202.     }
  203. }
  204.  
  205. //---------------------------------------------------------------------------
  206. //  ParseTreePair
  207. //  ╧≡ε÷σΣ≤≡α Γ√ßε≡ΩΦ ∩≤≥σΘ Ωε∩Φ≡εΓαφΦ 
  208. //---------------------------------------------------------------------------
  209. BOOL ParseTreePair (int argc, char** argv)
  210. {
  211.     int ArgCount = 0;                   // ±≈╕≥≈ΦΩ α≡π≤∞σφ≥εΓ
  212.     for (int nArg = 1; nArg < argc; nArg++) // ÷ΦΩδ εßτε≡α ∩α≡α∞σ≥≡εΓ
  213.     {
  214.         char* pArg = argv[nArg];        // ε≈σ≡σΣφεΘ α≡π≤∞σφ≥
  215.         if (*pArg != '-')               // ²≥ε φσ Ωδ■≈
  216.         {
  217.             if (ArgCount > 1)           // ²≥ε ≤µσ δΦ°φσσ
  218.             {
  219.                 ShowAlert ("Too many path arguments or syntax error in command line\0\0╙Ωαταφε ±δΦ°Ωε∞ ∞φεπε ∩≤≥σΘ ΦδΦ ±Φφ≥αΩ÷Φ≈σ±Ωα  ε°ΦßΩα Γ Ωε∞σφΣφεΘ ±≥≡εΩσ",
  220.                   MB_OK | MB_ICONSTOP); // ±εεß∙Φ≥ⁿ ε φσ∩≡Φ ≥φε±≥ ⌡
  221.                 ExitCode |= EXIT_SYNTAX_ERROR;  // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  222.                 return FALSE;           // Γσ≡φ≤≥ⁿ ⌠δαπ ε°ΦßΩΦ
  223.             }
  224.             wchar_t* cBuffer;
  225.             int nCoded;
  226.             if (!MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, pArg, -1,
  227.               (wchar_t*) WBuffer2, 10240 / sizeof (wchar_t) - 1) || // φσ ≤Σαδε±ⁿ ∩≡σεß≡ατεΓαφΦσ Γ Unicode
  228.               ((nCoded = GetFullPathNameW ((wchar_t*) WBuffer2,
  229.               10240 / sizeof (wchar_t) - 1, (wchar_t*) WBuffer1, &cBuffer)) == 0))  // φσ ≤Σαδε±ⁿ ∩εδ≤≈Φ≥ⁿ ∩εδφ√Θ ∩≤≥ⁿ
  230.             {
  231.                 ShowAlert ("Unicode path convertion failed\nMay be a syntax error in command line\0\0═σΓετ∞εµφε ∩≡σεß≡ατεΓα≥ⁿ ∩≤≥ⁿ Γ Unicode\n┬ετ∞εµφε, ²≥ε ±Φφ≥αΩ±Φ≈σ±Ωα  ε°ΦßΩα Γ Ωε∞αφΣφεΘ ±≥≡εΩσ",
  232.                   MB_OK | MB_ICONSTOP); // ±εεß∙Φ≥ⁿ εß ε°ΦßΩσ
  233.                 ExitCode |= EXIT_SYNTAX_ERROR;  // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  234.                 return FALSE;           // Γσ≡φ≤≥ⁿ ≡στ≤δⁿ≥α≥
  235.             }
  236.             cBuffer = ((wchar_t*) WBuffer1) + nCoded - 1;   // Γ Ωεφσ÷ ±≥≡εΩΦ
  237.             if (*cBuffer++ != L'\\')    // ≡ατΣσδΦ≥σδ  φσ≥
  238.                 *cBuffer++ = L'\\';     // ∩εΣ±≥αΓΦ≥ⁿ
  239.             if (!ArgCount) cBuffer = _wcspcpy (cBuffer, L"*.*");    // Σδ  Φ±≥ε≈φΦΩα ΣεßαΓΦ≥ⁿ ∞α±Ω≤
  240.             *cBuffer = 0;               // ταΩ≡√≥ⁿ ±≥≡εΩ≤
  241.             cBuffer = (wchar_t*) malloc ((wcslen ((wchar_t*) WBuffer1) + 1) * sizeof (wchar_t));    // τα⌡Γα≥Φ≥ⁿ ∩α∞ ≥ⁿ ∩εΣ ß≤⌠σ≡
  242.             if (!cBuffer)               // ß≤⌠σ≡ φσ Γ√Σσδσφ
  243.             {
  244.                 ShowAlert ("Insufficient memory\0\0═σΣε±≥α≥ε≈φε ∩α∞ ≥Φ Σδ  τα∩≤±Ωα ∩≡επ≡α∞∞√",
  245.                   MB_OK | MB_ICONSTOP); // ±εεß∙Φ≥ⁿ εß ε°ΦßΩσ
  246.                 ExitCode |= EXIT_NO_MEMORY; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  247.                 return FALSE;           // Γσ≡φ≤≥ⁿ ≡στ≤δⁿ≥α≥
  248.             }
  249.             wcscpy (cBuffer, (wchar_t*) WBuffer1);  // ±Ωε∩Φ≡εΓα≥ⁿ ≡στ≤δⁿ≥α≥
  250.             if (ArgCount++) DestinationPath = cBuffer;  // Γ≥ε≡εΘ α≡π≤∞σφ≥ - Ω≤Σα
  251.             else SourcePath = cBuffer;  // ∩σ≡Γ√Θ α≡π≤∞σφ≥ - ε≥Ω≤Σα
  252.         }
  253.     }
  254.     return TRUE;                        // Γ±╕ Γ√∩εδφσφε
  255. }
  256.  
  257. //---------------------------------------------------------------------------
  258. //  WriteLogString
  259. //  ╧≡ε÷σΣ≤≡α Γ√ΓεΣα ±≥≡εΩΦ Γ ⌠αΘδ ∩≡ε≥εΩεδα
  260. //---------------------------------------------------------------------------
  261. void WriteLogString (char* LString, BOOL bBreak)
  262. {
  263.     char* pBuffer = LString;            // ∩≡σΣ∩εδαπασ∞ Γ√ΓεΣ φα ΣΦ±Ω
  264.     if (!DiskOut)                       // φσ≥, Γ≡εΣσ ß√ φα ²Ω≡αφ
  265.     {
  266.         CharToOemA (LString, OEMBuffer);    // ∩≡σεß≡ατεΓα≥ⁿ
  267.         pBuffer = OEMBuffer;            // ∩εΣ∞σφΦ≥ⁿ ≤Ωατα≥σδⁿ
  268.     }
  269.     printf ("%s", pBuffer);             // Γ√Γσ±≥Φ
  270.     if (bBreak) printf ("\n");          // φα ±δσΣ≤■∙≤■ ±≥≡εΩ≤
  271. }
  272.  
  273. //---------------------------------------------------------------------------
  274. //  WriteLogMessage
  275. //  ╧≡ε÷σΣ≤≡α Γ√ΓεΣα ∞φεπε τ√≈φεπε ∩≡ε≥εΩεδα
  276. //---------------------------------------------------------------------------
  277. void WriteLogMessage (char* EString, char* RString)
  278. {
  279.     if (UseRussian <= 0) WriteLogString (EString, TRUE);    // Γ√Γσ±≥Φ αφπδΦΘ±Ω≤■ ±≥≡εΩ≤
  280.     if (UseRussian) WriteLogString (RString, TRUE); // Γ√Γσ±≥Φ ≡≤±±Ω≤■ ±≥≡εΩ≤
  281. }
  282.  
  283. //---------------------------------------------------------------------------
  284. //  WriteLogFile
  285. //  ╧≡ε÷σΣ≤≡α Γ√ΓεΣα Γ ∩≡ε≥εΩεδ Φ∞σφΦ ⌠αΘδα
  286. //---------------------------------------------------------------------------
  287. void WriteLogFile (wchar_t* FileString, void* WBuffer, BOOL bBreak)
  288. {
  289.     int nCoded = WideCharToMultiByte (CP_ACP, 0, FileString, -1, (char*) WBuffer,
  290.       10230, NULL, NULL);               // ∩≡σεß≡ατεΓα≥ⁿ Φ∞  ⌠αΘδα
  291.     if (!nCoded)                        // ∩≡σεß≡ατεΓαφΦσ φσ Γ√∩εδφσφε
  292.         *((char*) WBuffer) = 0;         // επ≡αφΦ≈Φ≥σδⁿ
  293.     WriteLogString ((char*) WBuffer, bBreak);   // Γ√Γσ±≥Φ
  294. }
  295.  
  296. //---------------------------------------------------------------------------
  297. //  LogFileAlert
  298. //  ╧≡ε÷σΣ≤≡α Γ√ΓεΣα Γ ∩≡ε≥εΩεδ ±εεß∙σφΦΘ εß ε°ΦßΩα⌡
  299. //---------------------------------------------------------------------------
  300. void LogFileAlert (wchar_t* FileString, void* WBuffer, char* EString, char* ETrail,
  301.   char* RString, char* RTrail)
  302. {
  303.     if (UseRussian <= 0)                // ≡ατ≡σ°╕φ αφπδΦΘ±ΩΦΘ  τ√Ω
  304.     {
  305.         WriteLogString (EString, FALSE);    // φα≈αδε ±εεß∙σφΦ 
  306.         WriteLogFile (FileString, WBuffer, FALSE);  // Φ∞  ⌠αΘδα
  307.         WriteLogString (ETrail, TRUE);  // ⌡Γε±≥ ±εεß∙σφΦ 
  308.     }
  309.     if (UseRussian)                     // ≡ατ≡σ°╕φ ≡≤±±ΩΦΘ  τ√Ω
  310.     {
  311.         WriteLogString (RString, FALSE);    // φα≈αδε ±εεß∙σφΦ 
  312.         WriteLogFile (FileString, WBuffer, FALSE);  // Φ∞  ⌠αΘδα
  313.         WriteLogString (RTrail, TRUE);  // ⌡Γε±≥ ±εεß∙σφΦ 
  314.     }
  315. }
  316.  
  317. //---------------------------------------------------------------------------
  318. //  ShowFileAlert
  319. //  ╧≡ε÷σΣ≤≡α Γ√ΓεΣα ±εεß∙σφΦ  ±ε ±∩σ÷Φ⌠ΦΩα÷ΦσΘ ⌠αΘδα
  320. //---------------------------------------------------------------------------
  321. int ShowFileAlert (wchar_t* FileString, int nStrLength, char* EString, char* ETrail,
  322.   char* RString, char* RTrail, UINT uIcon)
  323. {
  324.     wchar_t* sBuffer = FileString;      // Φ±⌡εΣφα  ±≥≡εΩα
  325.     if (nStrLength >= 0)                // Γτ ≥ⁿ ≈α±≥ⁿ ±≥≡εΩΦ
  326.     {
  327.         sBuffer = (wchar_t*) WBuffer2;  // ∩≡ε∞σµ≤≥ε≈φ√Θ ß≤⌠σ≡
  328.         if (nStrLength) memcpy (WBuffer2, FileString, nStrLength * sizeof (wchar_t));  // ±Ωε∩Φ≡εΓα≥ⁿ ≈α±≥ⁿ ±≥≡εΩΦ
  329.         sBuffer[nStrLength] = 0;        // ταΩ≡√≥ⁿ ±≥≡εΩ≤
  330.     }
  331.     char* cBuffer = (char*) WBuffer1;   // ß≤⌠σ≡ ∩≡σεß≡ατεΓαφΦ 
  332.     *cBuffer++ = ':'; *cBuffer++ = '\n';    // ΓΓεΣφ√σ ±Φ∞Γεδ√
  333.     int nCoded = WideCharToMultiByte (CP_ACP, 0, sBuffer, -1, cBuffer, 10230,
  334.       NULL, NULL);                      // ∩≡σεß≡ατεΓα≥ⁿ ∩≤≥ⁿ
  335.     if (!nCoded)                        // ∩≡σεß≡ατεΓαφΦσ φσ Γ√∩εδφσφε
  336.         *((char*) WBuffer1) = 0;        // επ≡αφΦ≈Φ≥σδⁿ
  337.     cBuffer = (char*) WBuffer2;         // Γ≥ε≡εΘ ß≤⌠σ≡
  338.     cBuffer = stpcpy (cBuffer, EString);    // αφπδΦΘ±Ωα  ±≥≡εΩα ±εεß∙σφΦ 
  339.     cBuffer = stpcpy (cBuffer, (char*) WBuffer1);   // Φ∞  ⌠αΘδα
  340.     cBuffer = stpcpy (cBuffer, ETrail); // αφπδΦΘ±ΩΦΘ ⌡Γε±≥ ±εεß∙σφΦ 
  341.     *cBuffer++ = 0; *cBuffer++ = 0;     // ≡ατΣσδΦ≥σδⁿ  τ√ΩεΓ
  342.     cBuffer = stpcpy (cBuffer, RString);    // ≡≤±±Ωα  ±≥≡εΩα ±εεß∙σφΦ 
  343.     cBuffer = stpcpy (cBuffer, (char*) WBuffer1);   // Φ∞  ⌠αΘδα
  344.     stpcpy (cBuffer, RTrail);           // ≡≤±±ΩΦΘ ⌡Γε±≥ ±εεß∙σφΦ 
  345.     return ShowAlert ((char*) WBuffer2, uIcon); // Γ√Γσ±≥Φ ±εεß∙σφΦσ
  346. }
  347.  
  348. //---------------------------------------------------------------------------
  349. //  Concatenate
  350. //  ╧≡ε÷σΣ≤≡α ±δΦ φΦ  ±≥≡εΩ
  351. //---------------------------------------------------------------------------
  352. wchar_t* Concatenate (wchar_t* S1, int n1, wchar_t* S2, int n2, wchar_t* S3, int n3)
  353. {
  354.     if (n1 < 0) n1 = wcslen (S1);       // ε∩≡σΣσδΦ≥ⁿ Φ±≥Φφφ√σ ≡ατ∞σ≡√ ±≥≡εΩ
  355.     if (n2 < 0) n2 = wcslen (S2);
  356.     if (n3 < 0) n3 = wcslen (S3);
  357.     wchar_t* Sp = (wchar_t*) malloc ((n1 + n2 + n3 + 1) * sizeof (wchar_t));    // τα⌡Γα≥Φ≥ⁿ ∩α∞ ≥ⁿ
  358.     if (Sp)                             // ∩α∞ ≥ⁿ Γ√Σσδσφα
  359.     {
  360.         wchar_t* pSp = Sp;              // ±Ωε∩Φ≡εΓα≥ⁿ φα≈αδⁿφ√Θ ≤Ωατα≥σδⁿ
  361.         if (n1 > 0) pSp = ((wchar_t*) memcpy (pSp, S1, n1 * sizeof (wchar_t))) + n1;    // ∩σ≡Γα  ∩εΣ±≥≡εΩα
  362.         if (n2 > 0) pSp = ((wchar_t*) memcpy (pSp, S2, n2 * sizeof (wchar_t))) + n2;    // Γ≥ε≡α  ∩εΣ±≥≡εΩα
  363.         if (n3 > 0) pSp = ((wchar_t*) memcpy (pSp, S3, n3 * sizeof (wchar_t))) + n3;    // ≥≡σ≥ⁿ  ∩εΣ±≥≡εΩα
  364.         *pSp = 0;                       // ταΩ≡√≥ⁿ ±≥≡εΩ≤
  365.     }
  366.     return Sp;                          // Γσ≡φ≤≥ⁿ ≡στ≤δⁿ≥α≥
  367. }
  368.  
  369. //---------------------------------------------------------------------------
  370. //  GetPathLength
  371. //  ╧≡ε÷σΣ≤≡α ε∩≡σΣσδσφΦ  ΣδΦφ√ ∩≤≥Φ
  372. //---------------------------------------------------------------------------
  373. int GetPathLength (wchar_t* FString)
  374. {
  375.     int nResult = 0;                    // ≡στ≤δⁿ≥α≥
  376.     int nIndex = 0;                     // ΦφΣσΩ± ∩σ≡σßε≡α
  377.     while (FString[nIndex])             // Γ±  ±≥≡εΩα Σε Ωεφ÷α
  378.     {
  379.         if (FString[nIndex++] == L'\\') // εßφα≡≤µσφ ≡ατΣσδΦ≥σδⁿ
  380.             nResult = nIndex;           // τα⌠ΦΩ±Φ≡εΓα≥ⁿ ΣδΦφ≤
  381.     }
  382.     return nResult;                     // Γσ≡φ≤≥ⁿ ≡στ≤δⁿ≥α≥
  383. }
  384.  
  385. //---------------------------------------------------------------------------
  386. //  TransferCompressionStatus
  387. //  ╧≡ε÷σΣ≤≡α ∩σ≡σφε±α ±ε±≥ε φΦ  Ωε∞∩≡σ±±ΦΦ
  388. //---------------------------------------------------------------------------
  389. BOOL TransferCompressionStatus (wchar_t* PSource, wchar_t* PDest)
  390. {
  391.     USHORT StatusBuffer;                // ß≤⌠σ≡ Σδ  ±≈Φ≥√ΓαφΦ  ±≥α≥≤±α
  392.     DWORD nResult;                      // ß≤⌠σ≡ Σδ  ≡στ≤δⁿ≥α≥α ε∩σ≡α÷ΦΦ
  393.     int nErrorCode;                     // Σδ  ΩεΣα ε°ΦßΩΦ
  394.     DWORD dwAttrib = GetFileAttributesW (PSource);  // ∩εδ≤≈Φ≥ⁿ α≥≡Φß≤≥√ Φ±≥ε≈φΦΩα
  395.     if (dwAttrib == 0xFFFFFFFF)         // φσ ∩≡ε≈Φ≥αδΦ±ⁿ
  396.     {
  397.         nErrorCode = GetLastError ();   // ∩εδ≤≈Φ≥ⁿ ΩεΣ ε°ΦßΩΦ
  398.         if ((nErrorCode == ERROR_FILE_NOT_FOUND) || (nErrorCode == ERROR_PATH_NOT_FOUND) ||
  399.           (nErrorCode == 67))           // φσ φαΘΣσφ ∩≤≥ⁿ ΦδΦ ⌠αΘδ
  400.         {
  401.             ExitCode |= EXIT_NOT_FOUND; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  402.             return (ShowFileAlert (PSource, -1, "File, directory or path not found", "",
  403.               "╘αΘδ, Ωα≥αδεπ ΦδΦ ∩≤≥ⁿ φσ φαΘΣσφ", "",
  404.               MB_OKCANCEL | MB_ICONWARNING) == IDOK);   // ±εεß∙Φ≥ⁿ
  405.         }
  406.         if (nErrorCode == ERROR_ACCESS_DENIED)  // τα∩≡σ∙╕φ Σε±≥≤∩
  407.         {
  408.             ExitCode |= EXIT_ACCESS_DENIED; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  409.             return (ShowFileAlert (PSource, -1, "Access denied", "", "─ε±≥≤∩ τα∩≡σ∙╕φ", "",
  410.               MB_OKCANCEL | MB_ICONWARNING) == IDOK);   // ±εεß∙Φ≥ⁿ
  411.         }
  412.         if (nErrorCode == ERROR_NOT_ENOUGH_MEMORY)  // φσ ⌡Γα≥Φδε ≡σ±≤≡±εΓ
  413.         {
  414.             ShowAlert ("Insufficient memory or system resources\0\0═σΣε±≥α≥ε≈φε ∩α∞ ≥Φ ΦδΦ ±Φ±≥σ∞φ√⌡ ≡σ±≤≡±εΓ",
  415.               MB_OK | MB_ICONSTOP);     // ±εεß∙Φ≥ⁿ
  416.             ExitCode |= EXIT_NO_MEMORY; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  417.             return FALSE;               // ∩≡σ≡Γα≥ⁿ
  418.         }
  419.         if ((nErrorCode == ERROR_INVALID_DRIVE) || (nErrorCode == ERROR_INVALID_NAME))  // ε°ΦßΩα Γ ±∩σ÷Φ⌠ΦΩα÷ΦΦ ⌠αΘδα
  420.         {
  421.             ExitCode |= EXIT_SYNTAX_ERROR;  // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  422.             ShowFileAlert (PSource, -1, "Invalid drive or another error in path", "",
  423.               "═σΣε±≥≤∩φεσ ≤±≥≡εΘ±≥Γε ΦδΦ Σ≡≤πα  ε°ΦßΩα Γ ταΣαφΦΦ ∩≤≥Φ", "",
  424.               MB_OK | MB_ICONWARNING);  // ±εεß∙Φ≥ⁿ
  425.             return FALSE;               // ∩≡σ≡Γα≥ⁿ
  426.         }
  427.         ShowSystemAlert (nErrorCode);   // ±εεß∙Φ≥ⁿ ε ±Φ±≥σ∞φεΘ ε°ΦßΩσ
  428.         return FALSE;                   // ∩≡σ≡Γα≥ⁿ ≡αßε≥≤
  429.     }
  430.     HANDLE hPtr = CreateFileW (PSource, 0,
  431.       FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
  432.       FILE_FLAG_BACKUP_SEMANTICS, NULL);    // ε≥Ω≡√≥ⁿ Φ±≥ε≈φΦΩ
  433.     if (hPtr == INVALID_HANDLE_VALUE)   // ε≥Ω≡√≥ⁿ φσ ∩εδ≤≈Φδε±ⁿ
  434.     {
  435.         nErrorCode = GetLastError ();   // ∩εδ≤≈Φ≥ⁿ ΩεΣ ε°ΦßΩΦ
  436.         if ((nErrorCode == ERROR_FILE_NOT_FOUND) || (nErrorCode == ERROR_PATH_NOT_FOUND) ||
  437.           (nErrorCode == 67))           // φσ φαΘΣσφ ∩≤≥ⁿ ΦδΦ ⌠αΘδ
  438.         {
  439.             ExitCode |= EXIT_NOT_FOUND; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  440.             return (ShowFileAlert (PSource, -1, "File, directory or path not found", "",
  441.               "╘αΘδ, Ωα≥αδεπ ΦδΦ ∩≤≥ⁿ φσ φαΘΣσφ", "",
  442.               MB_OKCANCEL | MB_ICONWARNING) == IDOK);   // ±εεß∙Φ≥ⁿ
  443.         }
  444.         if (nErrorCode == ERROR_ACCESS_DENIED)  // τα∩≡σ∙╕φ Σε±≥≤∩
  445.         {
  446.             ExitCode |= EXIT_ACCESS_DENIED; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  447.             return (ShowFileAlert (PSource, -1, "Access denied", "", "─ε±≥≤∩ τα∩≡σ∙╕φ", "",
  448.               MB_OKCANCEL | MB_ICONWARNING) == IDOK);   // ±εεß∙Φ≥ⁿ
  449.         }
  450.         if (nErrorCode == ERROR_NOT_ENOUGH_MEMORY)  // φσ ⌡Γα≥Φδε ≡σ±≤≡±εΓ
  451.         {
  452.             ShowAlert ("Insufficient memory or system resources\0\0═σΣε±≥α≥ε≈φε ∩α∞ ≥Φ ΦδΦ ±Φ±≥σ∞φ√⌡ ≡σ±≤≡±εΓ",
  453.               MB_OK | MB_ICONSTOP);     // ±εεß∙Φ≥ⁿ
  454.             ExitCode |= EXIT_NO_MEMORY; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  455.             return FALSE;               // ∩≡σ≡Γα≥ⁿ
  456.         }
  457.         if ((nErrorCode == ERROR_INVALID_DRIVE) || (nErrorCode == ERROR_INVALID_NAME))  // ε°ΦßΩα Γ ±∩σ÷Φ⌠ΦΩα÷ΦΦ ⌠αΘδα
  458.         {
  459.             ExitCode |= EXIT_SYNTAX_ERROR;  // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  460.             ShowFileAlert (PSource, -1, "Invalid drive or another error in path", "",
  461.               "═σΣε±≥≤∩φεσ ≤±≥≡εΘ±≥Γε ΦδΦ Σ≡≤πα  ε°ΦßΩα Γ ταΣαφΦΦ ∩≤≥Φ", "",
  462.               MB_OK | MB_ICONWARNING);  // ±εεß∙Φ≥ⁿ
  463.             return FALSE;               // ∩≡σ≡Γα≥ⁿ
  464.         }
  465.         ShowSystemAlert (nErrorCode);   // ±εεß∙Φ≥ⁿ ε ±Φ±≥σ∞φεΘ ε°ΦßΩσ
  466.         return FALSE;                   // ∩≡σ≡Γα≥ⁿ ≡αßε≥≤
  467.     }
  468.     BOOL bExStat = DeviceIoControl (hPtr, FSCTL_GET_COMPRESSION, NULL, 0,
  469.       &StatusBuffer, sizeof (USHORT), &nResult, NULL);  // ∩≡ε≈Φ≥α≥ⁿ ±≥α≥≤± Φ±≥ε≈φΦΩα
  470.     nErrorCode = GetLastError ();       // ∩εδ≤≈Φ≥ⁿ ΩεΣ ε°ΦßΩΦ
  471.     CloseHandle (hPtr);                 // ταΩ≡√≥ⁿ ≤Ωατα≥σδⁿ
  472.     if (!bExStat)                       // ≈≥σφΦ  φσ ∩εδ≤≈Φδε±ⁿ
  473.     {
  474.         if (nErrorCode == ERROR_ACCESS_DENIED)  // τα∩≡σ∙╕φ Σε±≥≤∩
  475.         {
  476.             ExitCode |= EXIT_ACCESS_DENIED; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  477.             return (ShowFileAlert (PSource, -1, "Access denied", "", "─ε±≥≤∩ τα∩≡σ∙╕φ", "",
  478.               MB_OKCANCEL | MB_ICONWARNING) == IDOK);   // ±εεß∙Φ≥ⁿ
  479.         }
  480.         if (nErrorCode == ERROR_NOT_ENOUGH_MEMORY)  // φσ ⌡Γα≥Φδε ≡σ±≤≡±εΓ
  481.         {
  482.             ShowAlert ("Insufficient memory or system resources\0\0═σΣε±≥α≥ε≈φε ∩α∞ ≥Φ ΦδΦ ±Φ±≥σ∞φ√⌡ ≡σ±≤≡±εΓ",
  483.               MB_OK | MB_ICONSTOP);     // ±εεß∙Φ≥ⁿ
  484.             ExitCode |= EXIT_NO_MEMORY; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  485.             return FALSE;               // ∩≡σ≡Γα≥ⁿ
  486.         }
  487.         ShowSystemAlert (nErrorCode);   // ±εεß∙Φ≥ⁿ ε ±Φ±≥σ∞φεΘ ε°ΦßΩσ
  488.         return FALSE;                   // ∩≡σ≡Γα≥ⁿ ≡αßε≥≤
  489.     }
  490.     if (!SetFileAttributesW (PDest, FILE_ATTRIBUTE_NORMAL)) // Γ≡σ∞σφφε ±ß≡ε±Φ≥ⁿ α≥≡Φß≤≥√ φσ ∩εδ≤≈Φδε±ⁿ
  491.     {
  492.         nErrorCode = GetLastError ();   // ∩εδ≤≈Φ≥ⁿ ΩεΣ ε°ΦßΩΦ
  493.         if ((nErrorCode == ERROR_FILE_NOT_FOUND) || (nErrorCode == ERROR_PATH_NOT_FOUND) ||
  494.           (nErrorCode == 67))           // φσ φαΘΣσφ ∩≤≥ⁿ ΦδΦ ⌠αΘδ
  495.         {
  496.             ExitCode |= EXIT_NOT_FOUND; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  497.             return (ShowFileAlert (PDest, -1, "File, directory or path not found", "",
  498.               "╘αΘδ, Ωα≥αδεπ ΦδΦ ∩≤≥ⁿ φσ φαΘΣσφ", "",
  499.               MB_OKCANCEL | MB_ICONWARNING) == IDOK);   // ±εεß∙Φ≥ⁿ
  500.         }
  501.         if (nErrorCode == ERROR_ACCESS_DENIED)  // τα∩≡σ∙╕φ Σε±≥≤∩
  502.         {
  503.             ExitCode |= EXIT_ACCESS_DENIED; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  504.             return (ShowFileAlert (PDest, -1, "Access denied", "", "─ε±≥≤∩ τα∩≡σ∙╕φ", "",
  505.               MB_OKCANCEL | MB_ICONWARNING) == IDOK);   // ±εεß∙Φ≥ⁿ
  506.         }
  507.         if (nErrorCode == ERROR_NOT_ENOUGH_MEMORY)  // φσ ⌡Γα≥Φδε ≡σ±≤≡±εΓ
  508.         {
  509.             ShowAlert ("Insufficient memory or system resources\0\0═σΣε±≥α≥ε≈φε ∩α∞ ≥Φ ΦδΦ ±Φ±≥σ∞φ√⌡ ≡σ±≤≡±εΓ",
  510.               MB_OK | MB_ICONSTOP);     // ±εεß∙Φ≥ⁿ
  511.             ExitCode |= EXIT_NO_MEMORY; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  512.             return FALSE;               // ∩≡σ≡Γα≥ⁿ
  513.         }
  514.         if ((nErrorCode == ERROR_INVALID_DRIVE) || (nErrorCode == ERROR_INVALID_NAME))  // ε°ΦßΩα Γ ±∩σ÷Φ⌠ΦΩα÷ΦΦ ⌠αΘδα
  515.         {
  516.             ExitCode |= EXIT_SYNTAX_ERROR;  // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  517.             ShowFileAlert (PDest, -1, "Invalid drive or another error in path", "",
  518.               "═σΣε±≥≤∩φεσ ≤±≥≡εΘ±≥Γε ΦδΦ Σ≡≤πα  ε°ΦßΩα Γ ταΣαφΦΦ ∩≤≥Φ", "",
  519.               MB_OK | MB_ICONWARNING);  // ±εεß∙Φ≥ⁿ
  520.             return FALSE;               // ∩≡σ≡Γα≥ⁿ
  521.         }
  522.         ShowSystemAlert (nErrorCode);   // ±εεß∙Φ≥ⁿ ε ±Φ±≥σ∞φεΘ ε°ΦßΩσ
  523.         return FALSE;                   // ∩≡σ≡Γα≥ⁿ ≡αßε≥≤
  524.     }
  525.     hPtr = CreateFileW (PDest, GENERIC_WRITE,
  526.       FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
  527.       FILE_FLAG_BACKUP_SEMANTICS, NULL);    // ε≥Ω≡√≥ⁿ Φ±≥ε≈φΦΩ
  528.     if (hPtr == INVALID_HANDLE_VALUE)   // ε≥Ω≡√≥ⁿ φσ ∩εδ≤≈Φδε±ⁿ
  529.     {
  530.         nErrorCode = GetLastError ();   // ∩εδ≤≈Φ≥ⁿ ΩεΣ ε°ΦßΩΦ
  531.         if ((nErrorCode == ERROR_FILE_NOT_FOUND) || (nErrorCode == ERROR_PATH_NOT_FOUND) ||
  532.           (nErrorCode == 67))           // φσ φαΘΣσφ ∩≤≥ⁿ ΦδΦ ⌠αΘδ
  533.         {
  534.             ExitCode |= EXIT_NOT_FOUND; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  535.             return (ShowFileAlert (PDest, -1, "File, directory or path not found", "",
  536.               "╘αΘδ, Ωα≥αδεπ ΦδΦ ∩≤≥ⁿ φσ φαΘΣσφ", "",
  537.               MB_OKCANCEL | MB_ICONWARNING) == IDOK);   // ±εεß∙Φ≥ⁿ
  538.         }
  539.         if (nErrorCode == ERROR_ACCESS_DENIED)  // τα∩≡σ∙╕φ Σε±≥≤∩
  540.         {
  541.             ExitCode |= EXIT_ACCESS_DENIED; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  542.             return (ShowFileAlert (PDest, -1, "Access denied", "", "─ε±≥≤∩ τα∩≡σ∙╕φ", "",
  543.               MB_OKCANCEL | MB_ICONWARNING) == IDOK);   // ±εεß∙Φ≥ⁿ
  544.         }
  545.         if (nErrorCode == ERROR_NOT_ENOUGH_MEMORY)  // φσ ⌡Γα≥Φδε ≡σ±≤≡±εΓ
  546.         {
  547.             ShowAlert ("Insufficient memory or system resources\0\0═σΣε±≥α≥ε≈φε ∩α∞ ≥Φ ΦδΦ ±Φ±≥σ∞φ√⌡ ≡σ±≤≡±εΓ",
  548.               MB_OK | MB_ICONSTOP);     // ±εεß∙Φ≥ⁿ
  549.             ExitCode |= EXIT_NO_MEMORY; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  550.             return FALSE;               // ∩≡σ≡Γα≥ⁿ
  551.         }
  552.         if ((nErrorCode == ERROR_INVALID_DRIVE) || (nErrorCode == ERROR_INVALID_NAME))  // ε°ΦßΩα Γ ±∩σ÷Φ⌠ΦΩα÷ΦΦ ⌠αΘδα
  553.         {
  554.             ExitCode |= EXIT_SYNTAX_ERROR;  // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  555.             ShowFileAlert (PDest, -1, "Invalid drive or another error in path", "",
  556.               "═σΣε±≥≤∩φεσ ≤±≥≡εΘ±≥Γε ΦδΦ Σ≡≤πα  ε°ΦßΩα Γ ταΣαφΦΦ ∩≤≥Φ", "",
  557.               MB_OK | MB_ICONWARNING);  // ±εεß∙Φ≥ⁿ
  558.             return FALSE;               // ∩≡σ≡Γα≥ⁿ
  559.         }
  560.         ShowSystemAlert (nErrorCode);   // ±εεß∙Φ≥ⁿ ε ±Φ±≥σ∞φεΘ ε°ΦßΩσ
  561.         return FALSE;                   // ∩≡σ≡Γα≥ⁿ ≡αßε≥≤
  562.     }
  563.     bExStat = DeviceIoControl (hPtr, FSCTL_SET_COMPRESSION,
  564.       &StatusBuffer, sizeof (USHORT), NULL, 0, &nResult, NULL); // ≤±≥αφεΓΦ≥ⁿ ±≥α≥≤± ∩≡Φ╕∞φΦΩα
  565.     nErrorCode = GetLastError ();       // ∩εδ≤≈Φ≥ⁿ ΩεΣ ε°ΦßΩΦ
  566.     CloseHandle (hPtr);                 // ταΩ≡√≥ⁿ ≤Ωατα≥σδⁿ
  567.     if (!bExStat)                       // ≈≥σφΦ  φσ ∩εδ≤≈Φδε±ⁿ
  568.     {
  569.         if (nErrorCode == ERROR_ACCESS_DENIED)  // τα∩≡σ∙╕φ Σε±≥≤∩
  570.         {
  571.             ExitCode |= EXIT_ACCESS_DENIED; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  572.             return (ShowFileAlert (PDest, -1, "Access denied", "", "─ε±≥≤∩ τα∩≡σ∙╕φ", "",
  573.               MB_OKCANCEL | MB_ICONWARNING) == IDOK);   // ±εεß∙Φ≥ⁿ
  574.         }
  575.         if (nErrorCode == ERROR_NOT_ENOUGH_MEMORY)  // φσ ⌡Γα≥Φδε ≡σ±≤≡±εΓ
  576.         {
  577.             ShowAlert ("Insufficient memory or system resources\0\0═σΣε±≥α≥ε≈φε ∩α∞ ≥Φ ΦδΦ ±Φ±≥σ∞φ√⌡ ≡σ±≤≡±εΓ",
  578.               MB_OK | MB_ICONSTOP);     // ±εεß∙Φ≥ⁿ
  579.             ExitCode |= EXIT_NO_MEMORY; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  580.             return FALSE;               // ∩≡σ≡Γα≥ⁿ
  581.         }
  582.         ShowSystemAlert (nErrorCode);   // ±εεß∙Φ≥ⁿ ε ±Φ±≥σ∞φεΘ ε°ΦßΩσ
  583.         return FALSE;                   // ∩≡σ≡Γα≥ⁿ ≡αßε≥≤
  584.     }
  585.     if (!SetFileAttributesW (PDest, dwAttrib))  // φσ ≤±≥αφεΓΦδΦ±ⁿ φ≤µφ√σ α≥≡Φß≤≥√
  586.     {
  587.         nErrorCode = GetLastError ();   // ∩εδ≤≈Φ≥ⁿ ΩεΣ ε°ΦßΩΦ
  588.         if ((nErrorCode == ERROR_FILE_NOT_FOUND) || (nErrorCode == ERROR_PATH_NOT_FOUND) ||
  589.           (nErrorCode == 67))           // φσ φαΘΣσφ ∩≤≥ⁿ ΦδΦ ⌠αΘδ
  590.         {
  591.             ExitCode |= EXIT_NOT_FOUND; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  592.             return (ShowFileAlert (PDest, -1, "File, directory or path not found", "",
  593.               "╘αΘδ, Ωα≥αδεπ ΦδΦ ∩≤≥ⁿ φσ φαΘΣσφ", "",
  594.               MB_OKCANCEL | MB_ICONWARNING) == IDOK);   // ±εεß∙Φ≥ⁿ
  595.         }
  596.         if (nErrorCode == ERROR_ACCESS_DENIED)  // τα∩≡σ∙╕φ Σε±≥≤∩
  597.         {
  598.             ExitCode |= EXIT_ACCESS_DENIED; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  599.             return (ShowFileAlert (PDest, -1, "Access denied", "", "─ε±≥≤∩ τα∩≡σ∙╕φ", "",
  600.               MB_OKCANCEL | MB_ICONWARNING) == IDOK);   // ±εεß∙Φ≥ⁿ
  601.         }
  602.         if (nErrorCode == ERROR_NOT_ENOUGH_MEMORY)  // φσ ⌡Γα≥Φδε ≡σ±≤≡±εΓ
  603.         {
  604.             ShowAlert ("Insufficient memory or system resources\0\0═σΣε±≥α≥ε≈φε ∩α∞ ≥Φ ΦδΦ ±Φ±≥σ∞φ√⌡ ≡σ±≤≡±εΓ",
  605.               MB_OK | MB_ICONSTOP);     // ±εεß∙Φ≥ⁿ
  606.             ExitCode |= EXIT_NO_MEMORY; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  607.             return FALSE;               // ∩≡σ≡Γα≥ⁿ
  608.         }
  609.         if ((nErrorCode == ERROR_INVALID_DRIVE) || (nErrorCode == ERROR_INVALID_NAME))  // ε°ΦßΩα Γ ±∩σ÷Φ⌠ΦΩα÷ΦΦ ⌠αΘδα
  610.         {
  611.             ExitCode |= EXIT_SYNTAX_ERROR;  // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  612.             ShowFileAlert (PDest, -1, "Invalid drive or another error in path", "",
  613.               "═σΣε±≥≤∩φεσ ≤±≥≡εΘ±≥Γε ΦδΦ Σ≡≤πα  ε°ΦßΩα Γ ταΣαφΦΦ ∩≤≥Φ", "",
  614.               MB_OK | MB_ICONWARNING);  // ±εεß∙Φ≥ⁿ
  615.             return FALSE;               // ∩≡σ≡Γα≥ⁿ
  616.         }
  617.         ShowSystemAlert (nErrorCode);   // ±εεß∙Φ≥ⁿ ε ±Φ±≥σ∞φεΘ ε°ΦßΩσ
  618.         return FALSE;                   // ∩≡σ≡Γα≥ⁿ ≡αßε≥≤
  619.     }
  620.     return TRUE;                        // Γ√∩εδφσφε
  621. }
  622.  
  623. //---------------------------------------------------------------------------
  624. //  TransferFile
  625. //  ╧≡ε÷σΣ≤≡α Ωε∩Φ≡εΓαφΦ  ε≈σ≡σΣφεπε ⌠αΘδα
  626. //---------------------------------------------------------------------------
  627. BOOL TransferFile (wchar_t* PSource, wchar_t* PDest)
  628. {
  629.     char DFlag = 0;                     // ⌠δαπ ε°ΦßΩΦ ± ∩εδ≤≈α≥σδσ∞
  630.     int nErrorCode = 0;                 // ΩεΣ ε°ΦßΩΦ
  631.     if (OverwriteFiles <= 0)            // ∩σ≡στα∩Φ±ⁿ ≥≡σß≤σ≥±  ΩαΩ ∞ΦφΦ∞≤∞ ∩εΣ≥Γσ≡ΣΦ≥ⁿ
  632.     {
  633.         DWORD dwAttrib = GetFileAttributesW (PDest);    // ∩≡εΓσ≡Φ≥ⁿ φαδΦ≈Φσ ÷σδσΓεπε ⌠αΘδα
  634.         if (dwAttrib == 0xFFFFFFFF)     // α≥≡Φß≤≥√ φσ ∩εδ≤≈σφ√
  635.             nErrorCode = GetLastError ();   // ∩εδ≤≈Φ≥ⁿ ΩεΣ ε°ΦßΩΦ
  636.         else
  637.         {
  638.             if (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)    // ²≥ε Ωα≥αδεπ
  639.             {
  640.                 ExitCode |= EXIT_INCOMPATIBLE_TYPES;    // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  641.                 if (ShowFileAlert (PDest, -1, "Directory already exists, file cannot be copied",
  642.                   "", "╙µσ ±≤∙σ±≥Γ≤σ≥ Ωα≥αδεπ, φσΓετ∞εµφε ±Ωε∩Φ≡εΓα≥ⁿ ⌠αΘδ", "",
  643.                   MB_OKCANCEL | MB_ICONWARNING) == IDCANCEL)    // ±εεß∙Φ≥ⁿ - ε≥∞σφα
  644.                     return FALSE;       // ∩≡σ≡Γα≥ⁿ ε∩σ≡α÷Φ■
  645.                 LogFileAlert (PDest, WBuffer1, "Directory already exists, file cannot be copied: ",
  646.                   " - skipped", "╙µσ ±≤∙σ±≥Γ≤σ≥ Ωα≥αδεπ, φσΓετ∞εµφε ±Ωε∩Φ≡εΓα≥ⁿ ⌠αΘδ: ",
  647.                   " - ∩≡ε∩≤∙σφ");       // Γ√Γσ±≥Φ Γ ∩≡ε≥εΩεδ
  648.                 return TRUE;            // ∞εµφε ∩≡εΣεδµα≥ⁿ
  649.             }
  650.             int nReply = (!OverwriteFiles) ? IDNO :
  651.               ShowFileAlert (PDest, -1, "File already exists", "\nOverwrite?",
  652.               "╘αΘδ ≤µσ ±≤∙σ±≥Γ≤σ≥", "\n╧σ≡σ∩Φ±α≥ⁿ?",
  653.               MB_YESNOCANCEL | MB_ICONQUESTION | MB_DEFBUTTON2);    // ≈≥ε Σσδα≥ⁿ?
  654.             if (nReply != IDYES) ExitCode |= EXIT_ALREADY_EXISTS;   // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  655.             if (nReply == IDCANCEL) return FALSE;   // ∩≡σ≡Γα≥ⁿ ε∩σ≡α÷Φ■
  656.             if (nReply == IDNO)         // ∩σ≡στα∩Φ±ⁿ ßδεΩΦ≡εΓαφα
  657.             {
  658.                 LogFileAlert (PDest, WBuffer1, "File already exists: ",
  659.                   " - skipped", "╘αΘδ ≤µσ ±≤∙σ±≥Γ≤σ≥: ", " - ∩≡ε∩≤∙σφ");    // Γ√Γσ±≥Φ Γ ∩≡ε≥εΩεδ
  660.                 return TRUE;            // ∞εµφε ∩≡εΣεδµα≥ⁿ
  661.             }
  662.             if (!SetFileAttributesW (PDest, FILE_ATTRIBUTE_NORMAL)) // ±ß≡ε±Φ≥ⁿ α≥≡Φß≤≥√ φσ ∩εδ≤≈Φδε±ⁿ
  663.                 nErrorCode = GetLastError ();   // ∩εδ≤≈Φ≥ⁿ ΩεΣ ε°ΦßΩΦ
  664.         }
  665.         if (nErrorCode == ERROR_FILE_NOT_FOUND) nErrorCode = 0; // ²≥ε φσ ε°ΦßΩα
  666.         DFlag = (nErrorCode != 0);      // ⌠δαπ ε°ΦßΩΦ
  667.     }
  668.     if (!nErrorCode &&                  // ∞εµφε Ωε∩Φ≡εΓα≥ⁿ
  669.       !CopyFileW (PSource, PDest, FALSE))   // α ±Ωε∩Φ≡εΓα≥ⁿ φσ ∩εδ≤≈Φδε±ⁿ
  670.     {
  671.         nErrorCode = GetLastError ();   // ∩εδ≤≈Φ≥ⁿ ΩεΣ ε°ΦßΩΦ
  672.         if (nErrorCode == ERROR_FILE_EXISTS)    // ⌠αΘδ ±≤∙σ±≥Γ≤σ≥
  673.         {
  674.             ExitCode |= EXIT_ALREADY_EXISTS;    // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  675.             if (ShowFileAlert (PDest, -1, "File already exists and cannot be overwritten", "",
  676.               "╘αΘδ ≤µσ ±≤∙σ±≥Γ≤σ≥ Φ φσ ∞εµσ≥ ß√≥ⁿ ∩σ≡σ∩Φ±αφ", "",
  677.               MB_OKCANCEL | MB_ICONWARNING) == IDCANCEL)    // ±εεß∙Φ≥ⁿ - ε≥∞σφα
  678.                 return FALSE;           // ∩≡σ≡Γα≥ⁿ ε∩σ≡α÷Φ■
  679.             LogFileAlert (PDest, WBuffer1, "File already exists and cannot be overwritten: ",
  680.               " - skipped", "╘αΘδ ≤µσ ±≤∙σ±≥Γ≤σ≥ Φ φσ ∞εµσ≥ ß√≥ⁿ ∩σ≡σ∩Φ±αφ: ",
  681.               " - ∩≡ε∩≤∙σφ");           // Γ√Γσ±≥Φ Γ ∩≡ε≥εΩεδ
  682.             return TRUE;                // ∞εµφε ∩≡εΣεδµα≥ⁿ
  683.         }
  684.     }
  685.     if ((nErrorCode == ERROR_FILE_NOT_FOUND) || (nErrorCode == ERROR_PATH_NOT_FOUND) ||
  686.       (nErrorCode == 67))               // φσ φαΘΣσφ ∩≤≥ⁿ ΦδΦ ⌠αΘδ
  687.     {
  688.         ExitCode |= EXIT_NOT_FOUND;     // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  689.         if (ShowFileAlert ((DFlag) ? PDest : PSource, -1,
  690.           "File or path not found", "", "╘αΘδ ΦδΦ ∩≤≥ⁿ φσ φαΘΣσφ", "",
  691.           MB_OKCANCEL | MB_ICONWARNING) == IDCANCEL)    // ±εεß∙Φ≥ⁿ - ε≥∞σφα
  692.             return FALSE;
  693.         LogFileAlert ((DFlag) ? PDest : PSource, WBuffer1, "File or path not found: ",
  694.           " - skipped", "╘αΘδ ΦδΦ ∩≤≥ⁿ φσ φαΘΣσφ: ", " - ∩≡ε∩≤∙σφ");    // Γ√Γσ±≥Φ Γ ∩≡ε≥εΩεδ
  695.         return TRUE;                    // ∞εµφε ∩≡εΣεδµα≥ⁿ
  696.     }
  697.     if (nErrorCode == ERROR_ACCESS_DENIED)  // τα∩≡σ∙╕φ Σε±≥≤∩
  698.     {
  699.         ExitCode |= EXIT_ACCESS_DENIED; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  700.         if (ShowFileAlert ((DFlag) ? PDest : PSource, -1, "Access denied", "",
  701.           "─ε±≥≤∩ τα∩≡σ∙╕φ", "", MB_OKCANCEL | MB_ICONWARNING) == IDCANCEL)     // ±εεß∙Φ≥ⁿ - ε≥∞σφα
  702.             return FALSE;
  703.         LogFileAlert ((DFlag) ? PDest : PSource, WBuffer1, "Access denied: ",
  704.           " - file skipped", "─ε±≥≤∩ τα∩≡σ∙╕φ: ", " - ⌠αΘδ ∩≡ε∩≤∙σφ");  // Γ√Γσ±≥Φ Γ ∩≡ε≥εΩεδ
  705.         return TRUE;                    // ∞εµφε ∩≡εΣεδµα≥ⁿ
  706.     }
  707.     if (nErrorCode == ERROR_NOT_ENOUGH_MEMORY)  // φσ ⌡Γα≥Φδε ≡σ±≤≡±εΓ
  708.     {
  709.         ShowAlert ("Insufficient memory or system resources\0\0═σΣε±≥α≥ε≈φε ∩α∞ ≥Φ ΦδΦ ±Φ±≥σ∞φ√⌡ ≡σ±≤≡±εΓ",
  710.           MB_OK | MB_ICONSTOP);         // ±εεß∙Φ≥ⁿ
  711.         ExitCode |= EXIT_NO_MEMORY;     // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  712.         return FALSE;                   // ∩≡σ≡Γα≥ⁿ
  713.     }
  714.     if ((nErrorCode == ERROR_INVALID_DRIVE) || (nErrorCode == ERROR_INVALID_NAME))  // ε°ΦßΩα Γ ±∩σ÷Φ⌠ΦΩα÷ΦΦ ⌠αΘδα
  715.     {
  716.         ExitCode |= EXIT_SYNTAX_ERROR;  // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  717.         ShowFileAlert ((DFlag) ? PDest : PSource, -1, "Invalid drive or another error in path", "",
  718.           "═σΣε±≥≤∩φεσ ≤±≥≡εΘ±≥Γε ΦδΦ Σ≡≤πα  ε°ΦßΩα Γ ταΣαφΦΦ ∩≤≥Φ", "",
  719.           MB_OK | MB_ICONWARNING);      // ±εεß∙Φ≥ⁿ
  720.         return FALSE;                   // ∩≡σ≡Γα≥ⁿ
  721.     }
  722.     if (nErrorCode)                     // ≡ατßε≡ ε°ΦßεΩ
  723.     {
  724.         ShowSystemAlert (nErrorCode);   // ±εεß∙Φ≥ⁿ ε ±Φ±≥σ∞φεΘ ε°ΦßΩσ
  725.         return FALSE;                   // ∩≡σ≡Γα≥ⁿ ≡αßε≥≤
  726.     }
  727.     if (!TransferCompressionStatus (PSource, PDest)) return FALSE;  // ε°ΦßΩα ∩σ≡σφε±α ±ε±≥ε φΦ  ±µα≥Φ 
  728.     WriteLogFile (PSource, WBuffer1, FALSE);    // ⌠αΘδ-Φ±≥ε≈φΦΩ
  729.     WriteLogString (" => ", FALSE);     // ≡ατΣσδΦ≥σδⁿ
  730.     WriteLogFile (PDest, WBuffer1, TRUE);   // ÷σδσΓεΘ ⌠αΘδ
  731.     return TRUE;                        // Γ√∩εδφσφε
  732. }
  733.  
  734. //---------------------------------------------------------------------------
  735. //  MakeTargetDirectory
  736. //  ╧≡ε÷σΣ≤≡α ±ετΣαφΦ  ÷σδσΓεπε ∩εΣΩα≥αδεπα
  737. //---------------------------------------------------------------------------
  738. int MakeTargetDirectory (wchar_t* PSource, wchar_t* PDest)
  739. {
  740.     int nLength = GetPathLength (PDest);    // Γ√ΣσδΦ≥ⁿ ΣδΦφ≤ ±εß±≥Γσφφε ∩≤≥Φ
  741.     DWORD dwAttrib = GetFileAttributesW (PDest);    // ∩≡εΓσ≡Φ≥ⁿ φαδΦ≈Φσ ⌠αΘδα / Ωα≥αδεπα
  742.     if ((dwAttrib == 0xFFFFFFFF) || !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) // Ωα≥αδεπα ≥ε≈φε φσ≥
  743.     {
  744.         if (dwAttrib != 0xFFFFFFFF)     // ≤Γ√, Φ∞σσ≥±  ⌠αΘδ
  745.         {
  746.             ExitCode |= EXIT_INCOMPATIBLE_TYPES;    // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  747.             if (ShowFileAlert (PDest, -1, "File already exists, directory cannot be created", "",
  748.               "╙µσ ±≤∙σ±≥Γ≤σ≥ ⌠αΘδ, φσΓετ∞εµφε ±ετΣα≥ⁿ Ωα≥αδεπ", "",
  749.               MB_OKCANCEL | MB_ICONWARNING) == IDCANCEL)    // ±εεß∙Φ≥ⁿ - ε≥∞σφα
  750.                 return -1;              // ⌠δαπ ε≥∞σφ√
  751.             LogFileAlert (PDest, WBuffer1, "File already exists, directory cannot be created: ",
  752.               " - skipped", "╙µσ ±≤∙σ±≥Γ≤σ≥ ⌠αΘδ, φσΓετ∞εµφε ±ετΣα≥ⁿ Ωα≥αδεπ: ",
  753.               " - ∩≡ε∩≤∙σφ");           // Γ√Γσ±≥Φ Γ ∩≡ε≥εΩεδ
  754.             return 0;                   // ∞εµφε ∩≡ε∩≤±≥Φ≥ⁿ
  755.         }
  756.         int nErrorCode = GetLastError ();   // ∩εδ≤≈Φ≥ⁿ ΩεΣ ε°ΦßΩΦ
  757.         if (nErrorCode == ERROR_FILE_NOT_FOUND) // ε≥±≤≥±≥ΓΦσ ⌠αΘδα - ²≥ε φε≡∞αδⁿφε
  758.             nErrorCode = CreateDirectoryW (PDest, NULL) ? 0 : GetLastError ();  // ±ετΣα≥ⁿ Ωα≥αδεπ
  759.         if ((nErrorCode == ERROR_PATH_NOT_FOUND) || (nErrorCode == 67)) // φσ φαΘΣσφ ∩≤≥ⁿ
  760.         {
  761.             ExitCode |= EXIT_NOT_FOUND; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  762.             if (ShowFileAlert (PDest, nLength, "Path not found", "", "╧≤≥ⁿ φσ φαΘΣσφ", "",
  763.               MB_OKCANCEL | MB_ICONWARNING) == IDCANCEL)    // ±εεß∙Φ≥ⁿ - ε≥∞σφα
  764.                 return -1;
  765.             LogFileAlert (PDest, WBuffer1, "Path not found: ", " - directory skipped",
  766.               "╧≤≥ⁿ φσ φαΘΣσφ: ", " - Ωα≥αδεπ ∩≡ε∩≤∙σφ");   // Γ√Γσ±≥Φ Γ ∩≡ε≥εΩεδ
  767.             return 0;                   // ∞εµφε ∩≡εΣεδµα≥ⁿ
  768.         }
  769.         if (nErrorCode == ERROR_ACCESS_DENIED)  // τα∩≡σ∙╕φ Σε±≥≤∩
  770.         {
  771.             ExitCode |= EXIT_ACCESS_DENIED; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  772.             if (ShowFileAlert (PDest, nLength, "Access denied", "", "─ε±≥≤∩ τα∩≡σ∙╕φ", "",
  773.               MB_OKCANCEL | MB_ICONWARNING) == IDOK)    // ±εεß∙Φ≥ⁿ - ε≥∞σφα
  774.                 return -1;
  775.             LogFileAlert (PDest, WBuffer1, "Access denied: ", " - directory skipped",
  776.               "─ε±≥≤∩ τα∩≡σ∙╕φ: ", " - Ωα≥αδεπ ∩≡ε∩≤∙σφ");   // Γ√Γσ±≥Φ Γ ∩≡ε≥εΩεδ
  777.             return 0;                   // ∞εµφε ∩≡εΣεδµα≥ⁿ
  778.         }
  779.         if (nErrorCode == ERROR_NOT_ENOUGH_MEMORY)  // φσ ⌡Γα≥Φδε ≡σ±≤≡±εΓ
  780.         {
  781.             ShowAlert ("Insufficient memory or system resources\0\0═σΣε±≥α≥ε≈φε ∩α∞ ≥Φ ΦδΦ ±Φ±≥σ∞φ√⌡ ≡σ±≤≡±εΓ",
  782.               MB_OK | MB_ICONSTOP);     // ±εεß∙Φ≥ⁿ
  783.             ExitCode |= EXIT_NO_MEMORY; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  784.             return -1;                  // ∩≡σ≡Γα≥ⁿ
  785.         }
  786.         if ((nErrorCode == ERROR_INVALID_DRIVE) || (nErrorCode == ERROR_INVALID_NAME))  // ε°ΦßΩα Γ ±∩σ÷Φ⌠ΦΩα÷ΦΦ ⌠αΘδα
  787.         {
  788.             ExitCode |= EXIT_SYNTAX_ERROR;  // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  789.             ShowFileAlert (PDest, nLength, "Invalid drive or another error in path", "",
  790.               "═σΣε±≥≤∩φεσ ≤±≥≡εΘ±≥Γε ΦδΦ Σ≡≤πα  ε°ΦßΩα Γ ταΣαφΦΦ ∩≤≥Φ", "",
  791.               MB_OK | MB_ICONWARNING);  // ±εεß∙Φ≥ⁿ
  792.             return -1;                  // ∩≡σ≡Γα≥ⁿ
  793.         }
  794.         if (nErrorCode)                 // ε°ΦßΩα
  795.         {
  796.             ShowSystemAlert (nErrorCode);   // ±εεß∙Φ≥ⁿ ε ±Φ±≥σ∞φεΘ ε°ΦßΩσ
  797.             return -1;                  // ∩≡σ≡Γα≥ⁿ ≡αßε≥≤
  798.         }
  799.     }
  800.     if (!TransferCompressionStatus (PSource, PDest)) return -1; // ε°ΦßΩα ∩σ≡σφε±α ±ε±≥ε φΦ  ±µα≥Φ 
  801.     if (dwAttrib == 0xFFFFFFFF)         // Ωα≥αδεπ ±ετΣαΓαδ± 
  802.     {
  803.         WriteLogFile (PSource, WBuffer1, FALSE);    // Ωα≥αδεπ-Φ±≥ε≈φΦΩ
  804.         WriteLogString ("\\ => ", FALSE);   // ≡ατΣσδΦ≥σδⁿ
  805.     }
  806.     else
  807.     {
  808.         WriteLogFile (PSource, WBuffer1, FALSE);    // Ωα≥αδεπ-Φ±≥ε≈φΦΩ
  809.         WriteLogString ("\\ == ", FALSE);   // ≡ατΣσδΦ≥σδⁿ
  810.     }
  811.     WriteLogFile (PDest, WBuffer1, FALSE);  // ÷σδσΓεΘ Ωα≥αδεπ
  812.     WriteLogString ("\\", TRUE);        // ≡ατΣσδΦ≥σδⁿ
  813.     return 1;                           // Γ√∩εδφσφε
  814. }
  815.  
  816. //---------------------------------------------------------------------------
  817. //  TransferAccessRights
  818. //  ╧≡ε÷σΣ≤≡α Ωε∩Φ≡εΓαφΦ  ∩≡αΓ Σε±≥≤∩α Σδ  ε≈σ≡σΣφεπε ⌠αΘδα ΦδΦ Ωα≥αδεπα
  819. //---------------------------------------------------------------------------
  820. int TransferAccessRights (wchar_t* PSource, wchar_t* PDest)
  821. {
  822.     int nErrorCode;                     // ΩεΣ ε°ΦßΩΦ
  823.     DWORD dwDAttrib = GetFileAttributesW (PDest);   // ∩εδ≤≈Φ≥ⁿ α≥≡Φß≤≥√ ÷σδσΓεπε ⌠αΘδα
  824.     if (dwDAttrib == 0xFFFFFFFF)        // φσ ∩εδ≤≈σφ√
  825.     {
  826.         nErrorCode = GetLastError ();   // ∩εδ≤≈Φ≥ⁿ ΩεΣ ε°ΦßΩΦ
  827.         if ((nErrorCode == ERROR_FILE_NOT_FOUND) || (nErrorCode == ERROR_PATH_NOT_FOUND) ||
  828.           (nErrorCode == 67))           // φσ φαΘΣσφ ∩≤≥ⁿ ΦδΦ ⌠αΘδ
  829.         {
  830.             if (!SkipCopy) return 0;    // φσ ß√δε ±Ωε∩Φ≡εΓαφε - τφα≈Φ≥, ≥αΩ φαΣε
  831.             ExitCode |= EXIT_NOT_FOUND; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  832.             if (ShowFileAlert (PDest, -1, "File, directory or path not found", "",
  833.               "╘αΘδ, Ωα≥αδεπ ΦδΦ ∩≤≥ⁿ φσ φαΘΣσφ", "",
  834.               MB_OKCANCEL | MB_ICONWARNING) == IDCANCEL)    // ±εεß∙Φ≥ⁿ - ε≥∞σφα
  835.                 return -1;              // ∩≡σ≡Γα≥ⁿ
  836.             LogFileAlert (PDest, WBuffer1, "File, directory or path not found: ",
  837.               " - skipped", "╘αΘδ, Ωα≥αδεπ ΦδΦ ∩≤≥ⁿ φσ φαΘΣσφ: ", " - ∩≡ε∩≤∙σφ");   // Γ√Γσ±≥Φ Γ ∩≡ε≥εΩεδ
  838.             return 0;                   // ∩≡εΣεδµΦ≥ⁿ
  839.         }
  840.         if (nErrorCode == ERROR_ACCESS_DENIED)  // τα∩≡σ∙╕φ Σε±≥≤∩
  841.         {
  842.             ExitCode |= EXIT_ACCESS_DENIED; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  843.             if (ShowFileAlert (PDest, -1, "Access denied", "", "─ε±≥≤∩ τα∩≡σ∙╕φ", "",
  844.               MB_OKCANCEL | MB_ICONWARNING) == IDCANCEL)    // ±εεß∙Φ≥ⁿ - ε≥∞σφα
  845.                 return -1;
  846.             LogFileAlert (PDest, WBuffer1, "Access denied: ", " - skipped",
  847.               "─ε±≥≤∩ τα∩≡σ∙╕φ: ", " - ∩≡ε∩≤∙σφ");  // Γ√Γσ±≥Φ Γ ∩≡ε≥εΩεδ
  848.             return 0;                   // ∞εµφε ∩≡εΣεδµα≥ⁿ
  849.         }
  850.         if (nErrorCode == ERROR_NOT_ENOUGH_MEMORY)  // φσ ⌡Γα≥Φδε ≡σ±≤≡±εΓ
  851.         {
  852.             ShowAlert ("Insufficient memory or system resources\0\0═σΣε±≥α≥ε≈φε ∩α∞ ≥Φ ΦδΦ ±Φ±≥σ∞φ√⌡ ≡σ±≤≡±εΓ",
  853.               MB_OK | MB_ICONSTOP);     // ±εεß∙Φ≥ⁿ
  854.             ExitCode |= EXIT_NO_MEMORY; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  855.             return -1;                  // ∩≡σ≡Γα≥ⁿ
  856.         }
  857.         if ((nErrorCode == ERROR_INVALID_DRIVE) || (nErrorCode == ERROR_INVALID_NAME))  // ε°ΦßΩα Γ ±∩σ÷Φ⌠ΦΩα÷ΦΦ ⌠αΘδα
  858.         {
  859.             ExitCode |= EXIT_SYNTAX_ERROR;  // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  860.             ShowFileAlert (PDest, -1, "Invalid drive or another error in path", "",
  861.               "═σΣε±≥≤∩φεσ ≤±≥≡εΘ±≥Γε ΦδΦ Σ≡≤πα  ε°ΦßΩα Γ ταΣαφΦΦ ∩≤≥Φ", "",
  862.               MB_OK | MB_ICONWARNING);  // ±εεß∙Φ≥ⁿ
  863.             return -1;                  // ∩≡σ≡Γα≥ⁿ
  864.         }
  865.         ShowSystemAlert (nErrorCode);   // ±εεß∙Φ≥ⁿ ε ±Φ±≥σ∞φεΘ ε°ΦßΩσ
  866.         return -1;                      // ∩≡σ≡Γα≥ⁿ ≡αßε≥≤
  867.     }
  868.     DWORD dwSAttrib = GetFileAttributesW (PSource); // ∩εδ≤≈Φ≥ⁿ α≥≡Φß≤≥√ Φ±≥ε≈φΦΩα
  869.     if (dwSAttrib == 0xFFFFFFFF)        // φσ ∩εδ≤≈σφ√
  870.     {
  871.         nErrorCode = GetLastError ();   // ∩εδ≤≈Φ≥ⁿ ΩεΣ ε°ΦßΩΦ
  872.         if ((nErrorCode == ERROR_FILE_NOT_FOUND) || (nErrorCode == ERROR_PATH_NOT_FOUND) ||
  873.           (nErrorCode == 67))           // φσ φαΘΣσφ ∩≤≥ⁿ ΦδΦ ⌠αΘδ
  874.         {
  875.             ExitCode |= EXIT_NOT_FOUND; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  876.             if (ShowFileAlert (PSource, -1, "File, directory or path not found", "",
  877.               "╘αΘδ, Ωα≥αδεπ ΦδΦ ∩≤≥ⁿ φσ φαΘΣσφ", "",
  878.               MB_OKCANCEL | MB_ICONWARNING) == IDCANCEL)    // ±εεß∙Φ≥ⁿ - ε≥∞σφα
  879.                 return -1;              // ∩≡σ≡Γα≥ⁿ
  880.             LogFileAlert (PSource, WBuffer1, "File, directory or path not found: ",
  881.               " - skipped", "╘αΘδ, Ωα≥αδεπ ΦδΦ ∩≤≥ⁿ φσ φαΘΣσφ: ", " - ∩≡ε∩≤∙σφ");   // Γ√Γσ±≥Φ Γ ∩≡ε≥εΩεδ
  882.             return 0;                   // ∩≡εΣεδµΦ≥ⁿ
  883.         }
  884.         if (nErrorCode == ERROR_ACCESS_DENIED)  // τα∩≡σ∙╕φ Σε±≥≤∩
  885.         {
  886.             ExitCode |= EXIT_ACCESS_DENIED; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  887.             if (ShowFileAlert (PSource, -1, "Access denied", "", "─ε±≥≤∩ τα∩≡σ∙╕φ", "",
  888.               MB_OKCANCEL | MB_ICONWARNING) == IDCANCEL)    // ±εεß∙Φ≥ⁿ - ε≥∞σφα
  889.                 return -1;
  890.             LogFileAlert (PSource, WBuffer1, "Access denied: ", " - skipped",
  891.               "─ε±≥≤∩ τα∩≡σ∙╕φ: ", " - ∩≡ε∩≤∙σφ");  // Γ√Γσ±≥Φ Γ ∩≡ε≥εΩεδ
  892.             return 0;                   // ∞εµφε ∩≡εΣεδµα≥ⁿ
  893.         }
  894.         if (nErrorCode == ERROR_NOT_ENOUGH_MEMORY)  // φσ ⌡Γα≥Φδε ≡σ±≤≡±εΓ
  895.         {
  896.             ShowAlert ("Insufficient memory or system resources\0\0═σΣε±≥α≥ε≈φε ∩α∞ ≥Φ ΦδΦ ±Φ±≥σ∞φ√⌡ ≡σ±≤≡±εΓ",
  897.               MB_OK | MB_ICONSTOP);     // ±εεß∙Φ≥ⁿ
  898.             ExitCode |= EXIT_NO_MEMORY; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  899.             return -1;                  // ∩≡σ≡Γα≥ⁿ
  900.         }
  901.         if ((nErrorCode == ERROR_INVALID_DRIVE) || (nErrorCode == ERROR_INVALID_NAME))  // ε°ΦßΩα Γ ±∩σ÷Φ⌠ΦΩα÷ΦΦ ⌠αΘδα
  902.         {
  903.             ExitCode |= EXIT_SYNTAX_ERROR;  // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  904.             ShowFileAlert (PSource, -1, "Invalid drive or another error in path", "",
  905.               "═σΣε±≥≤∩φεσ ≤±≥≡εΘ±≥Γε ΦδΦ Σ≡≤πα  ε°ΦßΩα Γ ταΣαφΦΦ ∩≤≥Φ", "",
  906.               MB_OK | MB_ICONWARNING);  // ±εεß∙Φ≥ⁿ
  907.             return -1;                  // ∩≡σ≡Γα≥ⁿ
  908.         }
  909.         ShowSystemAlert (nErrorCode);   // ±εεß∙Φ≥ⁿ ε ±Φ±≥σ∞φεΘ ε°ΦßΩσ
  910.         return -1;                      // ∩≡σ≡Γα≥ⁿ ≡αßε≥≤
  911.     }
  912.     dwDAttrib &= FILE_ATTRIBUTE_DIRECTORY;  // ε±≥αΓΦ≥ⁿ ≥εδⁿΩε ∩≡ΦτφαΩ Ωα≥αδεπα
  913.     dwSAttrib &= FILE_ATTRIBUTE_DIRECTORY;
  914.     if (dwDAttrib != dwSAttrib)         // φσ ±εΓ∩αΣα■≥ ≥Φ∩√ εß·σΩ≥εΓ
  915.     {
  916.         if (!SkipCopy) return 0;        // φσ ß√δε ±Ωε∩Φ≡εΓαφε - τφα≈Φ≥, ≥αΩ φαΣε
  917.         ExitCode |= EXIT_INCOMPATIBLE_TYPES;    // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  918.         if (ShowFileAlert (PSource, -1, (dwSAttrib) ? "Target is not a directory" : "Target is not a file",
  919.           "", (dwSAttrib) ? "╓σδσΓεΘ εß·σΩ≥ φσ  Γδ σ≥±  Ωα≥αδεπε∞" : "╓σδσΓεΘ εß·σΩ≥ φσ  Γδ σ≥±  ⌠αΘδε∞",
  920.           "", MB_OKCANCEL | MB_ICONWARNING) == IDCANCEL)    // ±εεß∙Φ≥ⁿ - ε≥∞σφα
  921.             return -1;
  922.         if (UseRussian <= 0)            // φ≤µσφ αφπδΦΘ±ΩΦΘ ≥σΩ±≥
  923.         {
  924.             WriteLogFile (PSource, WBuffer1, FALSE);    // ⌠αΘδ-Φ±≥ε≈φΦΩ
  925.             WriteLogString ((dwSAttrib) ? "\\ - target is not a directory " : " - target is not a file ", FALSE);
  926.             WriteLogFile (PDest, WBuffer1, FALSE);  // ÷σδσΓεΘ ⌠αΘδ
  927.             WriteLogString ((dwDAttrib) ? "\\" : "", FALSE);    // ταΩδ■≈Φ≥σδⁿφ√Θ ≡ατΣσδΦ≥σδⁿ
  928.             WriteLogString (" - skipped", TRUE);
  929.         }
  930.         if (UseRussian)                 // φ≤µσφ ≡≤±±ΩΦΘ ≥σΩ±≥
  931.         {
  932.             WriteLogFile (PSource, WBuffer1, FALSE);    // ⌠αΘδ-Φ±≥ε≈φΦΩ
  933.             WriteLogString ((dwSAttrib) ? "\\ - ÷σδσΓεΘ εß·σΩ≥ φσ  Γδ σ≥±  Ωα≥αδεπε∞ " : " - ÷σδσΓεΘ εß·σΩ≥ φσ  Γδ σ≥±  ⌠αΘδε∞ ", FALSE);
  934.             WriteLogFile (PDest, WBuffer1, FALSE);  // ÷σδσΓεΘ ⌠αΘδ
  935.             WriteLogString ((dwDAttrib) ? "\\" : "", FALSE);    // ταΩδ■≈Φ≥σδⁿφ√Θ ≡ατΣσδΦ≥σδⁿ
  936.             WriteLogString (" - ∩≡ε∩≤∙σφ", TRUE);
  937.         }
  938.         return 0;                       // ∞εµφε ∩≡εΣεδµα≥ⁿ
  939.     }
  940.     DWORD nLengthNeeded = 0;            // ß≤⌠σ≡ Σδ  ε∩≡σΣσδσφΦ  ≡ατ∞σ≡α ε∩Φ±α≥σδ 
  941.     PSECURITY_DESCRIPTOR pSecurity = NULL;  // ≤Ωατα≥σδⁿ φα ε∩Φ±α≥σδⁿ ∩≡αΓ Σε±≥≤∩α
  942.     nErrorCode = 0;                     // ε°ΦßεΩ ∩εΩα φσ≥
  943.     if (!GetFileSecurityW (PSource,
  944.       OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
  945.       (PSECURITY_DESCRIPTOR) WBuffer1, 0, &nLengthNeeded))  // φσ ≤Σα╕≥±  ∩≡ε≈Φ≥α≥ⁿ Φφ⌠ε≡∞α÷Φ■ ε ∩≡αΓα⌡ Σε±≥≤∩α
  946.     {
  947.         nErrorCode = GetLastError ();   // ε∩≡σΣσδΦ≥ⁿ ΩεΣ ε°ΦßΩΦ
  948.         if ((nErrorCode == ERROR_INSUFFICIENT_BUFFER) ||
  949.           (nErrorCode == ERROR_BUFFER_OVERFLOW))    // φσΣε±≥α≥ε≈φ√Θ ≡ατ∞σ≡ ß≤⌠σ≡α
  950.             nErrorCode = 0;             // ≥αΩ Φ Σεδµφε ß√≥ⁿ
  951.     }
  952.     if (!nErrorCode)                    // ∩σ≡Γ√Θ Γ√τεΓ ∩≡ε°╕δ
  953.     {
  954.         if (!nLengthNeeded) return 0;   // φΦ≈σπε φσ φαΣε Ωε∩Φ≡εΓα≥ⁿ
  955.         pSecurity = (PSECURITY_DESCRIPTOR) malloc (nLengthNeeded);  // τα⌡Γα≥Φ≥ⁿ ∩α∞ ≥ⁿ Σδ  ε∩Φ±α≥σδ 
  956.         if (!pSecurity)                 // ∩α∞ ≥ⁿ φσ Γ√Σσδσφα
  957.         {
  958.             ShowAlert ("Insufficient memory\0\0═σΣε±≥α≥ε≈φε ∩α∞ ≥Φ Σδ  Γ√∩εδφσφΦ  ∩≡επ≡α∞∞√",
  959.               MB_OK | MB_ICONSTOP);
  960.             ExitCode |= EXIT_NO_MEMORY; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  961.             return -1;                  // ∩≡σ≡Γα≥ⁿ Γ√∩εδφσφΦσ
  962.         }
  963.         DWORD nBufferLength = nLengthNeeded;    // τα∩ε∞φΦ≥ⁿ ≡ατ∞σ≡ ß≤⌠σ≡α
  964.         if (!GetFileSecurityW (PSource,
  965.           OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
  966.           pSecurity, nBufferLength, &nLengthNeeded))    // Φφ⌠ε≡∞α÷Φ  φσ ∩≡ε≈Φ≥αφα
  967.             nErrorCode = GetLastError ();   // ∩εδ≤≈Φ≥ⁿ ΩεΣ ε°ΦßΩΦ
  968.         else if (nLengthNeeded > nBufferLength) nErrorCode = ERROR_INSUFFICIENT_BUFFER; // φσ ⌡Γα≥Φδε ∩α∞ ≥Φ
  969.     }
  970.     if (nErrorCode && pSecurity) free (pSecurity);  // ∩≡Φ ε°ΦßΩσ ß≤⌠σ≡ φσ φ≤µσφ
  971.     if ((nErrorCode == ERROR_INSUFFICIENT_BUFFER) ||
  972.       (nErrorCode == ERROR_BUFFER_OVERFLOW))    // φσΣε±≥α≥ε≈φ√Θ ≡ατ∞σ≡ ß≤⌠σ≡α
  973.     {
  974.         ShowAlert ("Insufficient memory\0\0═σΣε±≥α≥ε≈φε ∩α∞ ≥Φ Σδ  Γ√∩εδφσφΦ  ∩≡επ≡α∞∞√",
  975.           MB_OK | MB_ICONSTOP);
  976.         ExitCode |= EXIT_NO_MEMORY;     // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  977.         return -1;                      // ∩≡σ≡Γα≥ⁿ Γ√∩εδφσφΦσ
  978.     }
  979.     if ((nErrorCode == ERROR_FILE_NOT_FOUND) || (nErrorCode == ERROR_PATH_NOT_FOUND) ||
  980.       (nErrorCode == 67))               // φσ φαΘΣσφ ∩≤≥ⁿ ΦδΦ ⌠αΘδ
  981.     {
  982.         ExitCode |= EXIT_NOT_FOUND;     // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  983.         if (ShowFileAlert (PSource, -1, "File, directory or path not found", "",
  984.           "╘αΘδ, Ωα≥αδεπ ΦδΦ ∩≤≥ⁿ φσ φαΘΣσφ", "",
  985.           MB_OKCANCEL | MB_ICONWARNING) == IDCANCEL)    // ±εεß∙Φ≥ⁿ - ε≥∞σφα
  986.             return -1;                  // ∩≡σ≡Γα≥ⁿ
  987.         LogFileAlert (PSource, WBuffer1, "File, directory or path not found: ",
  988.           " - skipped", "╘αΘδ, Ωα≥αδεπ ΦδΦ ∩≤≥ⁿ φσ φαΘΣσφ: ", " - ∩≡ε∩≤∙σφ");   // Γ√Γσ±≥Φ Γ ∩≡ε≥εΩεδ
  989.         return 0;                       // ∩≡εΣεδµΦ≥ⁿ
  990.     }
  991.     if ((nErrorCode == ERROR_ACCESS_DENIED) ||
  992.       (nErrorCode == 1314) || (nErrorCode == 1307)) // τα∩≡σ∙╕φ Σε±≥≤∩
  993.     {
  994.         ExitCode |= EXIT_ACCESS_DENIED; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  995.         if (ShowFileAlert (PSource, -1, "Access denied", "", "─ε±≥≤∩ τα∩≡σ∙╕φ", "",
  996.           MB_OKCANCEL | MB_ICONWARNING) == IDCANCEL)    // ±εεß∙Φ≥ⁿ - ε≥∞σφα
  997.             return -1;
  998.         LogFileAlert (PSource, WBuffer1, "Access denied: ", " - skipped",
  999.           "─ε±≥≤∩ τα∩≡σ∙╕φ: ", " - ∩≡ε∩≤∙σφ");  // Γ√Γσ±≥Φ Γ ∩≡ε≥εΩεδ
  1000.         return 0;                       // ∞εµφε ∩≡εΣεδµα≥ⁿ
  1001.     }
  1002.     if (nErrorCode == ERROR_NOT_ENOUGH_MEMORY)  // φσ ⌡Γα≥Φδε ≡σ±≤≡±εΓ
  1003.     {
  1004.         ShowAlert ("Insufficient memory or system resources\0\0═σΣε±≥α≥ε≈φε ∩α∞ ≥Φ ΦδΦ ±Φ±≥σ∞φ√⌡ ≡σ±≤≡±εΓ",
  1005.           MB_OK | MB_ICONSTOP);         // ±εεß∙Φ≥ⁿ
  1006.         ExitCode |= EXIT_NO_MEMORY;     // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  1007.         return -1;                      // ∩≡σ≡Γα≥ⁿ
  1008.     }
  1009.     if ((nErrorCode == ERROR_INVALID_DRIVE) || (nErrorCode == ERROR_INVALID_NAME))  // ε°ΦßΩα Γ ±∩σ÷Φ⌠ΦΩα÷ΦΦ ⌠αΘδα
  1010.     {
  1011.         ExitCode |= EXIT_SYNTAX_ERROR;  // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  1012.         ShowFileAlert (PSource, -1, "Invalid drive or another error in path", "",
  1013.           "═σΣε±≥≤∩φεσ ≤±≥≡εΘ±≥Γε ΦδΦ Σ≡≤πα  ε°ΦßΩα Γ ταΣαφΦΦ ∩≤≥Φ", "",
  1014.           MB_OK | MB_ICONWARNING);      // ±εεß∙Φ≥ⁿ
  1015.         return -1;                      // ∩≡σ≡Γα≥ⁿ
  1016.     }
  1017.     if (nErrorCode)                     // Γ±╕-≥αΩΦ ΩαΩα -≥ε ε°ΦßΩα
  1018.     {
  1019.         ShowSystemAlert (nErrorCode);   // ±εεß∙Φ≥ⁿ ε ±Φ±≥σ∞φεΘ ε°ΦßΩσ
  1020.         return -1;                      // ∩≡σ≡Γα≥ⁿ ≡αßε≥≤
  1021.     }
  1022.     if (!SetFileSecurityW (PDest,
  1023.       OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
  1024.       pSecurity))                       // ∩≡αΓα Σε±≥≤∩α φσ τα∩Φ±α≥ⁿ
  1025.         nErrorCode = GetLastError ();   // ∩εδ≤≈Φ≥ⁿ ΩεΣ ε°ΦßΩΦ
  1026.     free (pSecurity);                   // ε±ΓεßεΣΦ≥ⁿ ß≤⌠σ≡
  1027.     if ((nErrorCode == ERROR_FILE_NOT_FOUND) || (nErrorCode == ERROR_PATH_NOT_FOUND) ||
  1028.       (nErrorCode == 67))               // φσ φαΘΣσφ ∩≤≥ⁿ ΦδΦ ⌠αΘδ
  1029.     {
  1030.         if (!SkipCopy) return 0;        // φσ ß√δε ±Ωε∩Φ≡εΓαφε - τφα≈Φ≥, ≥αΩ φαΣε
  1031.         ExitCode |= EXIT_NOT_FOUND;     // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  1032.         if (ShowFileAlert (PDest, -1, "File, directory or path not found", "",
  1033.           "╘αΘδ, Ωα≥αδεπ ΦδΦ ∩≤≥ⁿ φσ φαΘΣσφ", "",
  1034.           MB_OKCANCEL | MB_ICONWARNING) == IDCANCEL)    // ±εεß∙Φ≥ⁿ - ε≥∞σφα
  1035.             return -1;                  // ∩≡σ≡Γα≥ⁿ
  1036.         LogFileAlert (PDest, WBuffer1, "File, directory or path not found: ",
  1037.           " - skipped", "╘αΘδ, Ωα≥αδεπ ΦδΦ ∩≤≥ⁿ φσ φαΘΣσφ: ", " - ∩≡ε∩≤∙σφ");   // Γ√Γσ±≥Φ Γ ∩≡ε≥εΩεδ
  1038.         return 0;                       // ∩≡εΣεδµΦ≥ⁿ
  1039.     }
  1040.     if ((nErrorCode == ERROR_ACCESS_DENIED) ||
  1041.       (nErrorCode == 1314) || (nErrorCode == 1307)) // τα∩≡σ∙╕φ Σε±≥≤∩
  1042.     {
  1043.         ExitCode |= EXIT_ACCESS_DENIED; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  1044.         if (ShowFileAlert (PDest, -1, "Access denied", "", "─ε±≥≤∩ τα∩≡σ∙╕φ", "",
  1045.           MB_OKCANCEL | MB_ICONWARNING) == IDCANCEL)    // ±εεß∙Φ≥ⁿ - ε≥∞σφα
  1046.             return -1;
  1047.         LogFileAlert (PDest, WBuffer1, "Access denied: ", " - skipped",
  1048.           "─ε±≥≤∩ τα∩≡σ∙╕φ: ", " - ∩≡ε∩≤∙σφ");  // Γ√Γσ±≥Φ Γ ∩≡ε≥εΩεδ
  1049.         return 0;                       // ∞εµφε ∩≡εΣεδµα≥ⁿ
  1050.     }
  1051.     if (nErrorCode == ERROR_NOT_ENOUGH_MEMORY)  // φσ ⌡Γα≥Φδε ≡σ±≤≡±εΓ
  1052.     {
  1053.         ShowAlert ("Insufficient memory or system resources\0\0═σΣε±≥α≥ε≈φε ∩α∞ ≥Φ ΦδΦ ±Φ±≥σ∞φ√⌡ ≡σ±≤≡±εΓ",
  1054.           MB_OK | MB_ICONSTOP);         // ±εεß∙Φ≥ⁿ
  1055.         ExitCode |= EXIT_NO_MEMORY;     // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  1056.         return -1;                      // ∩≡σ≡Γα≥ⁿ
  1057.     }
  1058.     if ((nErrorCode == ERROR_INVALID_DRIVE) || (nErrorCode == ERROR_INVALID_NAME))  // ε°ΦßΩα Γ ±∩σ÷Φ⌠ΦΩα÷ΦΦ ⌠αΘδα
  1059.     {
  1060.         ExitCode |= EXIT_SYNTAX_ERROR;  // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  1061.         ShowFileAlert (PDest, -1, "Invalid drive or another error in path", "",
  1062.           "═σΣε±≥≤∩φεσ ≤±≥≡εΘ±≥Γε ΦδΦ Σ≡≤πα  ε°ΦßΩα Γ ταΣαφΦΦ ∩≤≥Φ", "",
  1063.           MB_OK | MB_ICONWARNING);      // ±εεß∙Φ≥ⁿ
  1064.         return -1;                      // ∩≡σ≡Γα≥ⁿ
  1065.     }
  1066.     if (nErrorCode)                     // Γ±╕-≥αΩΦ ΩαΩα -≥ε ε°ΦßΩα
  1067.     {
  1068.         ShowSystemAlert (nErrorCode);   // ±εεß∙Φ≥ⁿ ε ±Φ±≥σ∞φεΘ ε°ΦßΩσ
  1069.         return -1;                      // ∩≡σ≡Γα≥ⁿ ≡αßε≥≤
  1070.     }
  1071.     WriteLogFile (PSource, WBuffer1, FALSE);    // ⌠αΘδ-Φ±≥ε≈φΦΩ
  1072.     WriteLogString ((dwDAttrib) ? "\\ => " : " => ", FALSE);    // ≡ατΣσδΦ≥σδⁿ
  1073.     WriteLogFile (PDest, WBuffer1, FALSE);   // ÷σδσΓεΘ ⌠αΘδ
  1074.     WriteLogString ((dwSAttrib) ? "\\" : "", TRUE); // ταΓσ≡°Φ≥ⁿ ±≥≡εΩ≤
  1075.     return 1;                           // Γ√∩εδφσφε
  1076. }
  1077.  
  1078. //---------------------------------------------------------------------------
  1079. //  ScanTree
  1080. //  ╧≡ε÷σΣ≤≡α ±ΩαφΦ≡εΓαφΦ  Σσ≡σΓα Ωα≥αδεπεΓ Φ ∩σ≡σφε±α ⌠αΘδεΓ / ∩≡αΓ
  1081. //---------------------------------------------------------------------------
  1082. BOOL ScanTree (wchar_t* PSource, wchar_t* PDest, int nPass)
  1083. {
  1084.     int nLength = GetPathLength (PSource);  // επ≡αφΦ≈σφΦσ ΣδΦφ√ ±∩σ÷Φ⌠ΦΩα÷ΦΦ
  1085.     HANDLE FindHandle = FindFirstFileW (PSource, &FileFinder);  // φαΘ≥Φ ∩σ≡Γ√Θ ⌠αΘδ
  1086.     DWORD nErrorCode = GetLastError (); // φα Γ± ΩΦΘ ±δ≤≈αΘ ΩεΣ ε°ΦßΩΦ
  1087.     if (FindHandle != INVALID_HANDLE_VALUE) // ⌠αΘδ φαΘΣσφ
  1088.     {
  1089.         BOOL bExStat = TRUE;            // ⌠δαπ Γ√∩εδφσφΦ 
  1090.         while (bExStat)                 // ∩εΩα ⌠αΘδ εßφα≡≤µΦΓασ≥± 
  1091.         {
  1092.             char cError = 0;            // ⌠δαπ ε°ΦßΩΦ
  1093.             wchar_t* SourceSpec = Concatenate (PSource, nLength, FileFinder.cFileName, -1,
  1094.               PSource, 0);              // ±⌠ε≡∞Φ≡εΓα≥ⁿ ±∩σ÷Φ⌠ΦΩα÷Φ■ Φ±≥ε≈φΦΩα
  1095.             wchar_t* DestSpec = Concatenate (PDest, -1, FileFinder.cFileName, -1, PDest, 0);    // ±⌠ε≡∞Φ≡εΓα≥ⁿ ÷σδσΓ≤■ ±∩σ÷Φ⌠ΦΩα÷Φ■
  1096.             if (!SourceSpec || !DestSpec)   // ∩α∞ ≥ⁿ φσ Γ√Σσδσφα
  1097.             {
  1098.                 ShowAlert ("Insufficient memory\0\0═σΣε±≥α≥ε≈φε ∩α∞ ≥Φ Σδ  Γ√∩εδφσφΦ  ∩≡επ≡α∞∞√",
  1099.                   MB_OK | MB_ICONSTOP);
  1100.                 ExitCode |= EXIT_NO_MEMORY; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  1101.                 cError = 1;             // ε≥∞σ≥Φ≥ⁿ ε°ΦßΩ≤
  1102.             }
  1103.             else if (FileFinder.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)    // ²≥ε Ωα≥αδεπ
  1104.             {
  1105.                 if (wcscmp (FileFinder.cFileName, L".") &&
  1106.                   wcscmp (FileFinder.cFileName, L"..")) // ²≥ε φσ ±δ≤µσßφ√σ τα∩Φ±Φ
  1107.                 {
  1108.                     if (nPass == 1)     // Ωε∩Φ≡εΓαφΦσ ∩εΣΩα≥αδεπεΓ
  1109.                     {
  1110.                         int nFlag = MakeTargetDirectory (SourceSpec, DestSpec); // ±ετΣα≥ⁿ ÷σδσΓεΘ ∩εΣΩα≥αδεπ
  1111.                         if (nFlag < 0) cError = 1;  // ±σ≡ⁿ╕τφα  ε°ΦßΩα
  1112.                         else if (nFlag) // ∩εΣΩα≥αδεπ ±ετΣαφ ΦδΦ ≤µσ ±≤∙σ±≥Γ≤σ≥
  1113.                         {
  1114.                             free (SourceSpec); free (DestSpec); // ε±ΓεßεΣΦ≥ⁿ ß≤⌠σ≡α
  1115.                             SourceSpec = Concatenate (PSource, nLength,
  1116.                               FileFinder.cFileName, -1, L"\\*.*", -1);  // ∞α±Ωα Σδ  ∩εΦ±Ωα Γφ≤≥≡Φ
  1117.                             DestSpec = Concatenate (PDest, -1, FileFinder.cFileName, -1,
  1118.                               L"\\", -1);   // ÷σδσΓεΘ Ωα≥αδεπ
  1119.                             if (!SourceSpec || !DestSpec)   // ∩α∞ ≥ⁿ φσ Γ√Σσδσφα
  1120.                             {
  1121.                                 ShowAlert ("Insufficient memory\0\0═σΣε±≥α≥ε≈φε ∩α∞ ≥Φ Σδ  Γ√∩εδφσφΦ  ∩≡επ≡α∞∞√",
  1122.                                   MB_OK | MB_ICONSTOP);
  1123.                                 ExitCode |= EXIT_NO_MEMORY; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  1124.                                 cError = 1; // ∩≡σ≡Γα≥ⁿ Γ√∩εδφσφΦσ
  1125.                             }
  1126.                             else if (!ScanTree (SourceSpec, DestSpec, 0) ||
  1127.                               !ScanTree (SourceSpec, DestSpec, 1))  // ±ßεΘ ∩≡Φ Ωε∩Φ≡εΓαφΦΦ ∩εΣΩα≥αδεπα
  1128.                                 cError = 1; // ∩≡σ≡Γα≥ⁿ Γ√∩εδφσφΦσ
  1129.                         }
  1130.                     }
  1131.                     else if (nPass == 3)    // Ωε∩Φ≡εΓαφΦσ ∩≡αΓ Σε±≥≤∩α Ω ∩εΣΩα≥αδεπα∞
  1132.                     {
  1133.                         int nFlag = TransferAccessRights (SourceSpec, DestSpec);    // ±Ωε∩Φ≡εΓα≥ⁿ ∩≡αΓα Σε±≥≤∩α
  1134.                         if (nFlag < 0) cError = 1;  // ε≥∞σ≥Φ≥ⁿ ε°ΦßΩ≤
  1135.                         else if (nFlag)     // ≤⌡εΣ Γπδ≤ßⁿ Γετ∞εµσφ
  1136.                         {
  1137.                             free (SourceSpec); free (DestSpec); // ε±ΓεßεΣΦ≥ⁿ ß≤⌠σ≡α
  1138.                             SourceSpec = Concatenate (PSource, nLength,
  1139.                               FileFinder.cFileName, -1, L"\\*.*", -1);  // ∞α±Ωα Σδ  ∩εΦ±Ωα Γφ≤≥≡Φ
  1140.                             DestSpec = Concatenate (PDest, -1, FileFinder.cFileName, -1,
  1141.                               L"\\", -1);   // ÷σδσΓεΘ Ωα≥αδεπ
  1142.                             if (!SourceSpec || !DestSpec)   // ∩α∞ ≥ⁿ φσ Γ√Σσδσφα
  1143.                             {
  1144.                                 ShowAlert ("Insufficient memory\0\0═σΣε±≥α≥ε≈φε ∩α∞ ≥Φ Σδ  Γ√∩εδφσφΦ  ∩≡επ≡α∞∞√",
  1145.                                   MB_OK | MB_ICONSTOP);
  1146.                                 ExitCode |= EXIT_NO_MEMORY; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  1147.                                 cError = 1; // ∩≡σ≡Γα≥ⁿ Γ√∩εδφσφΦσ
  1148.                             }
  1149.                             else if (!ScanTree (SourceSpec, DestSpec, 2) ||
  1150.                               !ScanTree (SourceSpec, DestSpec, 3))  // ±ßεΘ ∩≡Φ Ωε∩Φ≡εΓαφΦΦ ∩εΣΩα≥αδεπα
  1151.                                 cError = 1; // ∩≡σ≡Γα≥ⁿ Γ√∩εδφσφΦσ
  1152.                         }
  1153.                     }
  1154.                 }
  1155.             }
  1156.             else
  1157.             {
  1158.                 if (nPass == 0)         // Ωε∩Φ≡εΓαφΦσ ⌠αΘδεΓ
  1159.                 {
  1160.                     if (!TransferFile (SourceSpec, DestSpec))   // ⌠αΘδ φσ ±Ωε∩Φ≡εΓαφ
  1161.                         cError = 1;     // ε≥∞σ≥Φ≥ⁿ
  1162.                 }
  1163.                 else if (nPass == 2)    // Ωε∩Φ≡εΓαφΦσ ∩≡αΓ Σε±≥≤∩α Ω ⌠αΘδα∞
  1164.                 {
  1165.                     int nFlag = TransferAccessRights (SourceSpec, DestSpec);    // ±Ωε∩Φ≡εΓα≥ⁿ ∩≡αΓα Σε±≥≤∩α
  1166.                     if (nFlag < 0) cError = 1;  // ε≥∞σ≥Φ≥ⁿ ε°ΦßΩ≤
  1167.                 }
  1168.             }
  1169.             if (SourceSpec) free (SourceSpec);  // ε±ΓεßεΣΦ≥ⁿ Γ√Σσδσφφ≤■ ∩α∞ ≥ⁿ
  1170.             if (DestSpec) free (DestSpec);
  1171.             if (cError) return FALSE;   // ∩≡Φ ε°ΦßΩσ ∩≡σ≡Γα≥ⁿ Γ√∩εδφσφΦσ
  1172.             bExStat = FindNextFileW (FindHandle, &FileFinder);  // φαΘ≥Φ ±δσΣ≤■∙ΦΘ ⌠αΘδ
  1173.         }
  1174.         nErrorCode = GetLastError ();   // ∩εδ≤≈Φ≥ⁿ ΩεΣ ε°ΦßΩΦ
  1175.         if (!FindClose (FindHandle))    // φσ ∩εδ≤≈Φδε±ⁿ ταΩ≡√≥ⁿ ∩εΦ±Ω
  1176.         {
  1177.             ShowSystemAlert (GetLastError ());  // ±εεß∙Φ≥ⁿ ε ±Φ±≥σ∞φεΘ ε°ΦßΩσ
  1178.             return FALSE;               // ∩≡σ≡Γα≥ⁿ ≡αßε≥≤
  1179.         }
  1180.     }
  1181.     if ((nErrorCode == ERROR_FILE_NOT_FOUND) || (nErrorCode == ERROR_NO_MORE_FILES))    // ²≥ε φε≡∞αδⁿφε
  1182.         return TRUE;
  1183.     if ((nErrorCode == ERROR_PATH_NOT_FOUND) || (nErrorCode == 67)) // φσ φαΘΣσφ ∩≤≥ⁿ
  1184.     {
  1185.         ExitCode |= EXIT_NOT_FOUND;     // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  1186.         return (ShowFileAlert (PSource, nLength, "Path not found", "", "╧≤≥ⁿ φσ φαΘΣσφ", "",
  1187.           MB_OKCANCEL | MB_ICONWARNING) == IDOK);   // ±εεß∙Φ≥ⁿ
  1188.     }
  1189.     if (nErrorCode == ERROR_ACCESS_DENIED)  // τα∩≡σ∙╕φ Σε±≥≤∩
  1190.     {
  1191.         ExitCode |= EXIT_ACCESS_DENIED; // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  1192.         return (ShowFileAlert (PSource, nLength, "Access denied", "", "─ε±≥≤∩ τα∩≡σ∙╕φ", "",
  1193.           MB_OKCANCEL | MB_ICONWARNING) == IDOK);   // ±εεß∙Φ≥ⁿ
  1194.     }
  1195.     if ((nErrorCode == ERROR_NOT_ENOUGH_MEMORY) ||
  1196.       (nErrorCode == ERROR_NO_MORE_SEARCH_HANDLES)) // φσ ⌡Γα≥Φδε ≡σ±≤≡±εΓ
  1197.     {
  1198.         ShowAlert ("Insufficient memory or system resources\0\0═σΣε±≥α≥ε≈φε ∩α∞ ≥Φ ΦδΦ ±Φ±≥σ∞φ√⌡ ≡σ±≤≡±εΓ",
  1199.           MB_OK | MB_ICONSTOP);         // ±εεß∙Φ≥ⁿ
  1200.         ExitCode |= EXIT_NO_MEMORY;     // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  1201.         return FALSE;                   // ∩≡σ≡Γα≥ⁿ
  1202.     }
  1203.     if ((nErrorCode == ERROR_INVALID_DRIVE) || (nErrorCode == ERROR_INVALID_NAME))  // ε°ΦßΩα Γ ±∩σ÷Φ⌠ΦΩα÷ΦΦ ⌠αΘδα
  1204.     {
  1205.         ExitCode |= EXIT_SYNTAX_ERROR;  // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  1206.         ShowFileAlert (PSource, nLength, "Invalid drive or another error in path", "",
  1207.           "═σΣε±≥≤∩φεσ ≤±≥≡εΘ±≥Γε ΦδΦ Σ≡≤πα  ε°ΦßΩα Γ ταΣαφΦΦ ∩≤≥Φ", "",
  1208.           MB_OK | MB_ICONWARNING);      // ±εεß∙Φ≥ⁿ
  1209.         return FALSE;                   // ∩≡σ≡Γα≥ⁿ
  1210.     }
  1211.     ShowSystemAlert (nErrorCode);       // ±εεß∙Φ≥ⁿ ε ±Φ±≥σ∞φεΘ ε°ΦßΩσ
  1212.     return FALSE;                       // ∩≡σ≡Γα≥ⁿ ≡αßε≥≤
  1213. }
  1214.  
  1215. //---------------------------------------------------------------------------
  1216. //  GetPrivileges
  1217. //  ╧≡ε÷σΣ≤≡α ≤±≥αφεΓΩΦ φσεß⌡εΣΦ∞√⌡ ∩≡ΦΓΦδσπΦΘ ∩≡ε÷σ±±α
  1218. //  Know-How: Mark Russinovich and Bryce Cogswell
  1219. //---------------------------------------------------------------------------
  1220.  
  1221. BOOL GetPrivileges (void)
  1222. {
  1223.     HANDLE Client;
  1224.     int j;
  1225.     wchar_t* P[] = {                    // ±∩Φ±εΩ φσεß⌡εΣΦ∞√⌡ ∩≡ΦΓΦδσπΦΘ
  1226.         SE_TAKE_OWNERSHIP_NAME,
  1227.         SE_SECURITY_NAME,
  1228.         SE_BACKUP_NAME,
  1229.         SE_RESTORE_NAME,
  1230.         SE_MACHINE_ACCOUNT_NAME,
  1231.         SE_CHANGE_NOTIFY_NAME
  1232.     };
  1233.  
  1234.     if (!OpenProcessToken (GetCurrentProcess (), TOKEN_ADJUST_PRIVILEGES, &Client)) // ε≥Ω≡√≥ⁿ ∞α≡Ωσ≡ ßστε∩α±φε±≥Φ ∩≡ε÷σ±±α
  1235.         return FALSE;                   // φσ ≤Σαδε±ⁿ
  1236.     TOKEN_PRIVILEGES* Priv = (TOKEN_PRIVILEGES*) WBuffer1;  // ß≤⌠σ≡ Σδ  ⌠ε≡∞Φ≡εΓαφΦ  ±≥≡≤Ω≥≤≡√
  1237.     for (j = 0; j < sizeof (P) / sizeof (P[0]); ++j)    // Γ±σ φσεß⌡εΣΦ∞√σ ∩≡ΦΓΦδσπΦΦ
  1238.     {
  1239.         if (!LookupPrivilegeValueW (NULL, P[j], &Priv->Privileges[j].Luid)) // ∩εδ≤≈Φ≥ⁿ ΦΣσφ≥Φ⌠ΦΩα≥ε≡ ∩≡ΦΓΦδσπΦΦ
  1240.         {
  1241.             CloseHandle (Client);       // ταΩ≡√≥ⁿ ∞α≡Ωσ≡
  1242.             return FALSE;               // ∩≡ΦΓΦδσπΦ  φσ εßφα≡≤µσφα
  1243.         }
  1244.         Priv->Privileges[j].Attributes    = SE_PRIVILEGE_ENABLED; // ∩≡ΦΓΦδσπΦ■ ΓΩδ■≈Φ≥ⁿ
  1245.     }
  1246.     Priv->PrivilegeCount = sizeof (P) / sizeof (P[0]);  // ≈Φ±δε ∩≡ΦΓΦδσπΦΘ
  1247.     BOOL bExStat = AdjustTokenPrivileges (Client, FALSE, Priv, 0, NULL, NULL);  // τα∩≡ε±Φ≥ⁿ ≤±≥αφεΓΩ≤ ∩≡ΦΓΦδσπΦΘ
  1248.     CloseHandle (Client);               // ταΩ≡√≥ⁿ ∞α≡Ωσ≡
  1249.     return bExStat;                     // Γσ≡φ≤≥ⁿ ≡στ≤δⁿ≥α≥
  1250. }
  1251.  
  1252. //---------------------------------------------------------------------------
  1253. //  ╬±φεΓφα  ∩≡ε÷σΣ≤≡α
  1254. //---------------------------------------------------------------------------
  1255. int main (int argc, char** argv)
  1256. {
  1257.     ParseSwitches (argc, argv);         // ≡ατεß≡α≥ⁿ Ωδ■≈Φ
  1258.     {
  1259.         HANDLE StdOutHandle = GetStdHandle (STD_OUTPUT_HANDLE); // ∩εδ≤≈Φ≥ⁿ ΦΣσφ≥Φ⌠ΦΩα≥ε≡ ±≥αφΣα≡≥φεπε Γ√ΓεΣα
  1260.         if (StdOutHandle != INVALID_HANDLE_VALUE)   // ≈≥ε-≥ε ∩εδ≤≈σφε
  1261.             DiskOut = (GetFileType (StdOutHandle) == FILE_TYPE_DISK);   // ε≥∞σ≥Φ≥ⁿ Γ√ΓεΣ φα ΣΦ±Ω
  1262.     }
  1263.     WBuffer1 = malloc (10240);          // τα⌡Γα≥Φ≥ⁿ ≡αßε≈Φσ ß≤⌠σ≡α
  1264.     WBuffer2 = malloc (10240);
  1265.     if (!DiskOut) OEMBuffer = (char*) malloc (5120);
  1266.     if (!WBuffer1 || !WBuffer2 || (!DiskOut && !OEMBuffer)) // φ≤µφ√σ ß≤⌠σ≡α φσ τα⌡Γα≈σφ√
  1267.     {
  1268.         ShowAlert ("Insufficient memory\0\0═σΣε±≥α≥ε≈φε ∩α∞ ≥Φ Σδ  τα∩≤±Ωα ∩≡επ≡α∞∞√",
  1269.           MB_OK | MB_ICONSTOP);
  1270.         ExitCode |= EXIT_NO_MEMORY;     // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  1271.     }
  1272.     else if (CheckSystemVersion ())     // ²≥ε Windows NT
  1273.     {
  1274.         if (ParseTreePair (argc, argv) && SourcePath && DestinationPath)    // ∩≤≥Φ ≤±∩σ°φε Γ√Σσδσφ√
  1275.         {
  1276.             if (!GetPrivileges ())      // φσ ≤Σαδε±ⁿ ∩εδ≤≈Φ≥ⁿ φσεß⌡εΣΦ∞√σ ∩≡ΦΓΦδσπΦΦ
  1277.             {
  1278.                 ShowAlert ("Unable to obtain necessary privilege\0═σΓετ∞εµφε ∩εδ≤≈Φ≥ⁿ φσεß⌡εΣΦ∞√σ Σδ  ≡αßε≥√ ∩≡ΦΓΦδσπΦΦ",
  1279.                   MB_OK | MB_ICONSTOP);
  1280.                 ExitCode |= EXIT_PRIVILEGE_CHECK;   // ≤±≥αφεΓΦ≥ⁿ ΩεΣ ταΓσ≡°σφΦ 
  1281.             }
  1282.             else
  1283.             {
  1284.                 BOOL bExStat = TRUE;    // ∩εΩα Γ±╕ ⌡ε≡ε°ε
  1285.                 if (!SkipCopy)          // Ωε∩Φ≡εΓαφΦσ φσ ∩≡ε∩≤∙σφε
  1286.                 {
  1287.                     WriteLogMessage ("Copying files and folders:",
  1288.                       "╩ε∩Φ≡εΓαφΦσ ⌠αΘδεΓ Φ Ωα≥αδεπεΓ:");   // ταπεδεΓεΩ ∩≡ε≥εΩεδα
  1289.                     bExStat = ScanTree (SourcePath, DestinationPath, 0);    // ∩σ≡σφσ±≥Φ ⌠αΘδ√
  1290.                     if (bExStat) bExStat =
  1291.                       ScanTree (SourcePath, DestinationPath, 1);    // Φ ∩εΣΩα≥αδεπΦ
  1292.                 }
  1293.                 if (bExStat)            // Ωε∩Φ≡εΓαφΦσ φσ ±δσ≥σδε
  1294.                 {
  1295.                     WriteLogMessage ("Copying user access rights:",
  1296.                       "╩ε∩Φ≡εΓαφΦσ ∩≡αΓ Σε±≥≤∩α ∩εδⁿτεΓα≥σδσΘ:");   // ταπεδεΓεΩ ∩≡ε≥εΩεδα
  1297.                     bExStat = ScanTree (SourcePath, DestinationPath, 2);    // ∩σ≡σφσ±≥Φ ∩≡αΓα φα ⌠αΘδ√
  1298.                     if (bExStat) bExStat = ScanTree (SourcePath, DestinationPath, 3); // Φ ∩εΣΩα≥αδεπΦ
  1299.                     if (bExStat && CopyRootRights)  // ≥≡σß≤σ≥±  Ωε∩Φ≡εΓαφΦσ ∩≡αΓ Σε±≥≤∩α Ω Ωε≡φσΓε∞≤ Ωα≥αδεπ≤
  1300.                     {
  1301.                         wchar_t* LastSlash = wcsrchr (SourcePath, L'\\');   // φαΘ≥Φ ∩ε±δσΣφΦΘ ≡ατΣσδΦ≥σδⁿ
  1302.                         *(++LastSlash) = 0; // ε≥±σ≈ⁿ τΓστΣε≈ΩΦ
  1303.                         if (wcslen (SourcePath) > 3) *(--LastSlash) = 0;    // ≤ß≡α≥ⁿ ≡ατΣσδΦ≥σδⁿ, σ±δΦ ²≥ε φσ Ωε≡σφⁿ ΣΦ±Ωα
  1304.                         LastSlash = wcsrchr (DestinationPath, L'\\');   // φαΘ≥Φ ∩ε±δσΣφΦΘ ≡ατΣσδΦ≥σδⁿ
  1305.                         if (wcslen (DestinationPath) > 3) *LastSlash = 0;   // ≤ß≡α≥ⁿ ≡ατΣσδΦ≥σδⁿ, σ±δΦ ²≥ε φσ Ωε≡σφⁿ ΣΦ±Ωα
  1306.                         TransferAccessRights (SourcePath, DestinationPath); // Ωε∩Φ≡εΓα≥ⁿ ∩≡αΓα Σε±≥≤∩α Σδ  Ωε≡φ 
  1307.                     }
  1308.                 }
  1309.             }
  1310.         }
  1311.         else
  1312.         {
  1313.             if (UseRussian <= 0)        // Σε∩≤±≥Φ∞ αφπδΦΘ±ΩΦΘ
  1314.             {
  1315.                 WriteLogString ("\nNTCopy 1.0 - Copying files with user access rights\n", TRUE);
  1316.                 WriteLogString ("Usage:\n\tNTCopy [-switch] SourcePath [-switch] DestinationPath [-switch]", TRUE);
  1317.                 WriteLogString ("\nBoth SourcePath and DestinationPath are paths to the folders (may be relative)\nand can't contain wildcards", TRUE);
  1318.                 WriteLogString ("\nAvailable switches:", TRUE);
  1319.                 WriteLogString ("\t-l:e|r\tswitches to English or Russian language; uses both as default", TRUE);
  1320.                 WriteLogString ("\t-o:y|n\tenables (y) or disables (n) an overwriting of existing files;\n\t\tprompts to the user as default", TRUE);
  1321.                 WriteLogString ("\t-s\tskips file copying and sets user access rights for existing\n\t\tfiles", TRUE);
  1322.                 WriteLogString ("\t-r\tcopies user access rights for root directory", TRUE);
  1323.                 WriteLogString ("\nYou can use both uppercase and lowercase characters to set switches", TRUE);
  1324.             }
  1325.             if (UseRussian)             // Σε∩≤±≥Φ∞ ≡≤±±ΩΦΘ
  1326.             {
  1327.                 WriteLogString ("\nNTCopy 1.0 - ╩ε∩Φ≡εΓαφΦσ ⌠αΘδεΓ ± ∩≡αΓα∞Φ Σε±≥≤∩α ∩εδⁿτεΓα≥σδσΘ\n", TRUE);
  1328.                 WriteLogString ("┬√τεΓ:\n\tNTCopy [-Ωδ■≈] ╧≤≥ⁿ╬≥Ω≤Σα [-Ωδ■≈] ╧≤≥ⁿ╩≤Σα [-Ωδ■≈]", TRUE);
  1329.                 WriteLogString ("\n╧≤≥ⁿ╬≥Ω≤Σα Φ ╧≤≥ⁿ╩≤Σα - ²≥ε ∩≤≥Φ Ω Ωα≥αδεπα∞ (Γετ∞εµφε, ε≥φε±Φ≥σδⁿφ√σ);\nΓ φΦ⌡ φσδⁿτ  Φ±∩εδⁿτεΓα≥ⁿ ±Φ∞Γεδ√ π≡≤∩∩εΓ√⌡ ε∩σ≡α÷ΦΘ", TRUE);
  1330.                 WriteLogString ("\n─ε∩≤±≥Φ∞√σ Ωδ■≈Φ:", TRUE);
  1331.                 WriteLogString ("\t-l:e|r\t∩σ≡σΩδ■≈ασ≥ ∩≡επ≡α∞∞≤ φα αφπδΦΘ±ΩΦΘ (e) ΦδΦ ≡≤±±ΩΦΘ (r)  τ√Ω;\n\t\t∩ε ≤∞εδ≈αφΦ■ Φ±∩εδⁿτ≤■≥±  εßα  τ√Ωα ±εΓ∞σ±≥φε", TRUE);
  1332.                 WriteLogString ("\t-o:y|n\t≡ατ≡σ°ασ≥ (y) ΦδΦ τα∩≡σ∙ασ≥ (n) ∩σ≡στα∩Φ±ⁿ ±≤∙σ±≥Γ≤■∙Φ⌡ ⌠αΘδεΓ;\n\t\t∩ε ≤∞εδ≈αφΦ■ ∩εδⁿτεΓα≥σδ■ ταΣα╕≥±  Γε∩≡ε±", TRUE);
  1333.                 WriteLogString ("\t-s\t∩≡ε∩≤±Ωασ≥ Ωε∩Φ≡εΓαφΦσ ⌠αΘδεΓ Φ ≤±≥αφαΓδΦΓασ≥ ∩≡αΓα Σε±≥≤∩α\n\t\tΣδ  ±≤∙σ±≥Γ≤■∙Φ⌡ ⌠αΘδεΓ", TRUE);
  1334.                 WriteLogString ("\t-r\tΩε∩Φ≡≤σ≥ ∩≡αΓα Σε±≥≤∩α Σδ  Ωε≡φσΓεπε Ωα≥αδεπα", TRUE);
  1335.                 WriteLogString ("\n─δ  ≤ΩαταφΦ  Ωδ■≈σΘ Γ√ ∞εµσ≥σ Φ±∩εδⁿτεΓα≥ⁿ ±Φ∞Γεδ√ Γσ≡⌡φσπε Φ φΦµφσπε ≡σπΦ±≥≡α", TRUE);
  1336.             }
  1337.         }
  1338.     }
  1339.     if (SourcePath) free (SourcePath);  // ε±ΓεßεΣΦ≥ⁿ ß≤⌠σ≡α
  1340.     if (DestinationPath) free (DestinationPath);
  1341.     if (OEMBuffer) free (OEMBuffer);
  1342.     if (WBuffer1) free (WBuffer1);
  1343.     if (WBuffer2) free (WBuffer2);
  1344.     return ExitCode;
  1345. }
  1346. //---------------------------------------------------------------------------
  1347.  
  1348.